Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,98 +1,179 @@
|
|
1 |
import chainlit as cl
|
2 |
-
from
|
3 |
import instructor
|
4 |
from openai import OpenAI
|
5 |
import os
|
6 |
-
import
|
7 |
|
8 |
-
|
9 |
-
logging.basicConfig(level=logging.INFO)
|
10 |
-
logger = logging.getLogger(__name__)
|
11 |
|
12 |
# Patch the OpenAI client with Instructor
|
13 |
-
client = instructor.from_openai(OpenAI(api_key=os.
|
14 |
|
15 |
-
# Define
|
16 |
-
|
17 |
-
|
18 |
-
is_clear: str = Field(description="Is the proposed plan clear? It specifies which tools it needs to use and how. It lays out each component and how they all connect.")
|
19 |
-
is_detailed: str = Field(description="Is the proposed plan detailed? Each component should have a description of what it does.")
|
20 |
-
is_explicit: str = Field(description="Is the proposed plan explicit? Each component should have a data model to describe their input and output schema.")
|
21 |
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
24 |
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
# Define functions
|
29 |
-
def
|
30 |
-
return client.chat.completions.create(
|
31 |
-
model="gpt-4-turbo-preview",
|
32 |
-
response_model=UserProposal,
|
33 |
-
messages=[
|
34 |
-
{"role": "user", "content": user_proposal},
|
35 |
-
],
|
36 |
-
)
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
],
|
45 |
-
)
|
46 |
|
47 |
-
def revise_architecture(proposed_architecture: str) -> PropositionWithRevision:
|
48 |
return client.chat.completions.create(
|
49 |
model="gpt-4-turbo-preview",
|
50 |
-
response_model=
|
51 |
-
messages=
|
52 |
-
{"role": "user", "content": f"Revise the plan proposed: \n\n{proposed_architecture}\n\nThe plan should be a step by step implementation of software solution."},
|
53 |
-
],
|
54 |
)
|
55 |
|
56 |
# Define the Chainlit message handler
|
57 |
-
@cl.
|
58 |
-
async def
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
proposed_architecture = generate_proposed_architecture(user_proposal_details.proposal)
|
65 |
-
|
66 |
-
await cl.Message(
|
67 |
-
content=f"Proposed Architecture:\n{proposed_architecture.proposed_architecture}"
|
68 |
-
).send()
|
69 |
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
revised_architecture = revise_architecture(proposed_architecture.proposed_architecture)
|
75 |
-
|
76 |
-
await cl.Message(
|
77 |
-
content=f"Revised Architecture:\n{revised_architecture.revised_proposed_architecture}"
|
78 |
-
).send()
|
79 |
-
|
80 |
-
with open("output.md", "w") as output_file:
|
81 |
-
output_file.write("# User Proposal\n")
|
82 |
-
output_file.write(user_proposal_details.proposal + "\n\n")
|
83 |
-
output_file.write("# Proposed Architecture\n")
|
84 |
-
output_file.write(proposed_architecture.proposed_architecture + "\n\n")
|
85 |
-
output_file.write("# Revised Architecture\n")
|
86 |
-
output_file.write(revised_architecture.revised_proposed_architecture + "\n")
|
87 |
-
|
88 |
-
await cl.Message(
|
89 |
-
content="The results have been saved to output.md"
|
90 |
-
).send()
|
91 |
-
except Exception as e:
|
92 |
-
logger.error(f"An error occurred: {e}")
|
93 |
await cl.Message(
|
94 |
-
content="
|
95 |
).send()
|
96 |
|
97 |
-
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import chainlit as cl
|
2 |
+
from dotenv import load_dotenv
|
3 |
import instructor
|
4 |
from openai import OpenAI
|
5 |
import os
|
6 |
+
import json
|
7 |
|
8 |
+
load_dotenv()
|
|
|
|
|
9 |
|
10 |
# Patch the OpenAI client with Instructor
|
11 |
+
client = instructor.from_openai(OpenAI(api_key=os.environ['OPENAI_API_KEY']))
|
12 |
|
13 |
+
# Define prompt templates
|
14 |
+
PRD_PROMPT_TEMPLATE = """
|
15 |
+
### Product Requirements Document (PRD) for AI Applications
|
|
|
|
|
|
|
16 |
|
17 |
+
#### Introduction
|
18 |
+
- **Objective/Goal**:
|
19 |
+
- Explain the purpose of the AI application and what it aims to achieve.
|
20 |
+
- Provide a high-level overview of the release purpose.
|
21 |
+
- User Proposal: {user_proposal}
|
22 |
|
23 |
+
#### Features
|
24 |
+
- **Feature 1**:
|
25 |
+
- **Description**: Detailed description of the feature.
|
26 |
+
- **Goal**: What this feature aims to achieve.
|
27 |
+
- **Use Case**: Example of how a user would utilize this feature.
|
28 |
+
- **Additional Details**: Specifics such as out-of-scope items and prompt structure.
|
29 |
+
|
30 |
+
- **Feature 2**:
|
31 |
+
- **Description**: Detailed description of the feature.
|
32 |
+
- **Goal**: What this feature aims to achieve.
|
33 |
+
- **Use Case**: Example of how a user would utilize this feature.
|
34 |
+
- **Additional Details**: Specifics such as out-of-scope items and prompt structure.
|
35 |
+
|
36 |
+
*(Repeat for each feature)*
|
37 |
+
|
38 |
+
#### UX Flow & Design Notes
|
39 |
+
- **Overview**: General guidance required to ensure the release objectives are met.
|
40 |
+
- **User Workflow**: Describe the overall user workflow.
|
41 |
+
- **Design Considerations**: Any specific design notes relevant at this stage.
|
42 |
+
|
43 |
+
#### System & Environment Requirements
|
44 |
+
- **Supported Environments**:
|
45 |
+
- Browsers (e.g., Chrome, Firefox, Safari)
|
46 |
+
- Operating Systems (e.g., Windows 10, macOS)
|
47 |
+
- Memory and Processing Power requirements
|
48 |
+
|
49 |
+
#### Assumptions, Constraints & Dependencies
|
50 |
+
- **Assumptions**:
|
51 |
+
- List anything expected to be in place (e.g., all users will have Internet connectivity).
|
52 |
+
|
53 |
+
- **Constraints**:
|
54 |
+
- Dictate limits for the implementation (e.g., budgetary constraints, technical limitations).
|
55 |
+
|
56 |
+
- **Dependencies**:
|
57 |
+
- Conditions or items the product will rely on (e.g., relying on Google Maps for directions).
|
58 |
+
|
59 |
+
#### Prompt Engineering Practices
|
60 |
+
- **Ambiguity Mitigation**: Ensure clear, specific prompts to avoid ambiguous outputs. Evaluate prompts using examples and test consistency with different inputs.
|
61 |
+
- **Versioning**: Track and version each prompt to monitor performance changes over time.
|
62 |
+
- **Optimization**: Apply techniques like chain-of-thought prompting, majority voting, and breaking tasks into smaller prompts to improve output quality.
|
63 |
+
- **Cost & Latency Management**: Balance detailed prompts with cost efficiency and manage latency by optimizing token usage.
|
64 |
+
|
65 |
+
#### Task Composability
|
66 |
+
- **Multiple Tasks Composition**: Outline how multiple tasks interact, including sequential and parallel executions, and control flows like if statements and loops.
|
67 |
+
- **Agents and Tools**: Describe the use of agents to manage tasks and the integration of tools such as SQL executors and web browsers.
|
68 |
+
- **Control Flows**: Detail the use of control flows in managing tasks, including sequential, parallel, if statements, and loops.
|
69 |
+
|
70 |
+
#### Review & Approval Process
|
71 |
+
- **Initial Review**:
|
72 |
+
- Steps for internal product team review.
|
73 |
+
- Feedback incorporation.
|
74 |
+
|
75 |
+
- **Business Side Stakeholders Review**:
|
76 |
+
- Process for aligning with business stakeholders.
|
77 |
+
|
78 |
+
- **Engineering Handoff**:
|
79 |
+
- Clarifications and updates based on technical team feedback.
|
80 |
+
|
81 |
+
- **Final Approval**:
|
82 |
+
- Ensuring no surprises later on.
|
83 |
+
- Agreement from all teams involved (UX design, engineering, QA).
|
84 |
+
|
85 |
+
---
|
86 |
+
|
87 |
+
This PRD template is configured specifically for the user proposal: "{user_proposal}", ensuring a consistent format for every PRD, covering all necessary aspects from features to dependencies, review processes, and incorporating best practices in prompt engineering and task composability.
|
88 |
+
"""
|
89 |
+
|
90 |
+
DESIGNER_PROMPT_TEMPLATE = """
|
91 |
+
<System Message>
|
92 |
+
You are the Engineer/Designer Agent responsible for creating a functional product.
|
93 |
+
For a given proposal and PRD, write the simplest python script to quickly test your PoC. Only output python code and markdown.
|
94 |
+
</System Message>
|
95 |
+
\n<>####<>\n
|
96 |
+
<Context>
|
97 |
+
Proposed PRD:
|
98 |
+
{prd_response_raw}
|
99 |
+
\n<>####<>\n
|
100 |
+
Proposed PRD in its pydantic class form:
|
101 |
+
{prd_json}
|
102 |
+
</Context>
|
103 |
+
\n<>####<>\n
|
104 |
+
<Original User Proposal>
|
105 |
+
Original User Proposal:
|
106 |
+
{user_proposal}
|
107 |
+
</Original User Proposal>
|
108 |
+
\n<>####<>\n
|
109 |
+
<Instruction>
|
110 |
+
Guide the following instructions with the above system message and above context specifications as well as the original user proposal.
|
111 |
+
Write a simple AI application development plan for the user with as few steps as possible. Do not be verbose and explain the plan in an elementary school level.
|
112 |
+
The instructions to develop this Proof of Concept Implementation should only take one engineer about a day or two to complete.
|
113 |
+
Make sure what you are suggesting exist, so for each suggestion think step by step why you are suggesting it and how to find resources for that component.
|
114 |
+
Go to the below link, read it and use it as a reference guide for starting out:
|
115 |
+
https://raw.githubusercontent.com/AI-Maker-Space/Beyond-ChatGPT/main/README.md
|
116 |
+
</Instruction>
|
117 |
+
\n<>####<>\n
|
118 |
+
"""
|
119 |
+
|
120 |
+
# Function to format the templates with provided variables
|
121 |
+
def format_template(template, **kwargs):
|
122 |
+
return template.format(**kwargs)
|
123 |
|
124 |
# Define functions
|
125 |
+
def llm_call(user_prompt, system_prompt=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
+
messages = [
|
128 |
+
{"role": "user", "content": user_prompt}
|
129 |
+
] if system_prompt is None else [
|
130 |
+
{"role": "system", "content": system_prompt},
|
131 |
+
{"role": "user", "content": user_prompt},
|
132 |
+
]
|
|
|
|
|
133 |
|
|
|
134 |
return client.chat.completions.create(
|
135 |
model="gpt-4-turbo-preview",
|
136 |
+
response_model=None,
|
137 |
+
messages=messages,
|
|
|
|
|
138 |
)
|
139 |
|
140 |
# Define the Chainlit message handler
|
141 |
+
@cl.on_chat_start
|
142 |
+
async def start():
|
143 |
+
|
144 |
+
# Welcome message
|
145 |
+
wel_msg = cl.Message(content="Welcome to Build Advisor!\n\nBuild Advisor creates plan, production requirement spec and implementation for your AI application idea.\nQuickly create a PoC so you can determine whether an idea is worth starting, worth investing time and/or money in.")
|
146 |
+
await wel_msg.send()
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
+
# Ask user for AI application / business idea
|
149 |
+
res = await cl.AskUserMessage(content="What is your AI application/business idea?", timeout=30).send()
|
150 |
+
if res:
|
151 |
+
await wel_msg.remove()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
await cl.Message(
|
153 |
+
content=f"User Proposal: {res['output']}.\n\nStarting...",
|
154 |
).send()
|
155 |
|
156 |
+
user_proposal = res['output']
|
157 |
+
|
158 |
+
prd_sys1 = format_template(PRD_PROMPT_TEMPLATE, user_proposal=user_proposal) # system message to create PRD
|
159 |
+
prd_response_raw = llm_call(user_prompt=user_proposal, system_prompt=prd_sys1).choices[0].message.content # get PRD from LLM
|
160 |
+
|
161 |
+
# send PRD output to UI
|
162 |
+
prd_msg = cl.Message(content=prd_response_raw)
|
163 |
+
await prd_msg.send()
|
164 |
+
|
165 |
+
prd_json = json.dumps({"objective_goal": "Develop a chatbot...", "features": [], "ux_flow_design_notes": "...", "system_environment_requirements": "...", "assumptions": [], "constraints": [], "dependencies": [], "prompt_engineering_practices": "...", "task_composability": "...", "review_approval_process": "..."})
|
166 |
+
designer_prompt = format_template(DESIGNER_PROMPT_TEMPLATE, prd_response_raw=prd_response_raw, prd_json=prd_json, user_proposal=user_proposal)
|
167 |
+
designer_output = llm_call(designer_prompt).choices[0].message.content
|
168 |
+
|
169 |
+
designer_output_msg = cl.Message(content=designer_output)
|
170 |
+
await designer_output_msg.send()
|
171 |
+
|
172 |
+
# update outputs in UI
|
173 |
+
for secs in [1,5,10,20]:
|
174 |
+
await cl.sleep(secs)
|
175 |
+
await prd_msg.update()
|
176 |
+
await designer_output_msg.update()
|
177 |
+
|
178 |
+
# Load the starters ... overrided by on_chat_start
|
179 |
+
import starters
|