cmagganas commited on
Commit
b1286f0
·
verified ·
1 Parent(s): 6f0d9ec

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -75
app.py CHANGED
@@ -1,98 +1,179 @@
1
  import chainlit as cl
2
- from pydantic import BaseModel, Field
3
  import instructor
4
  from openai import OpenAI
5
  import os
6
- import logging
7
 
8
- # Set up logging
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.getenv('OPENAI_API_KEY')))
14
 
15
- # Define the Pydantic models
16
- class UserProposal(BaseModel):
17
- proposal: str = Field(description="This is the proposal of the original user prompt. It should be a clear concise detailed plan to use simple ai software tools to solve specific problem.")
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
- class ProposedArchitecture(BaseModel):
23
- proposed_architecture: str = Field(description="A detailed AI application architecture with all the tools required for the plan proposed. (e.g. Python packages)")
 
 
 
24
 
25
- class PropositionWithRevision(BaseModel):
26
- revised_proposed_architecture: str = Field(description="Step by step implementation of software solution.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  # Define functions
29
- def extract_user_proposal_details(user_proposal: str) -> UserProposal:
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
- def generate_proposed_architecture(proposal: str) -> ProposedArchitecture:
39
- return client.chat.completions.create(
40
- model="gpt-4-turbo-preview",
41
- response_model=ProposedArchitecture,
42
- messages=[
43
- {"role": "user", "content": f"Write a detailed AI application architecture with all the tools required for the plan proposed: \n\n{proposal}"},
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=PropositionWithRevision,
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.on_message
58
- async def main(message: cl.Message):
59
- try:
60
- user_proposal = message.content
61
-
62
- user_proposal_details = extract_user_proposal_details(user_proposal)
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
- feedback_message = await cl.AskUserMessage(content="What do you think about this proposed plan and alleged architecture?", timeout=60).send()
71
- if feedback_message:
72
- human_feedback_of_proposed_plan = feedback_message["output"]
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="An error occurred while processing your request. Please try again later."
95
  ).send()
96
 
97
- # Load the starters
98
- import starters
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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