File size: 15,127 Bytes
00eef43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1>Create React App Structure Using Multi Agents </h1>\n",
    "<h3>Use OpenAI and deepseek to create an app structure for React app. </h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's import environment variables\n",
    "from dotenv import load_dotenv\n",
    "load_dotenv(override=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "from typing import Dict, Any\n",
    "from IPython.display import Markdown, display\n",
    "from openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "openai_api_key = os.getenv('OPENAI_API_KEY')\n",
    "deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\n",
    "\n",
    "if not openai_api_key:\n",
    "    print('Missing OpenaAI API key.')\n",
    "if not deepseek_api_key:\n",
    "    print('Missing Deepseek API key')\n",
    "if openai_api_key and deepseek_api_key:\n",
    "    print(f'OpenAI: {openai_api_key[-10:]}\\n')\n",
    "    print(f'Deepseek: {deepseek_api_key[-10:]}\\n')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "app = {\"app_name\": \"Small Business Idea\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "openai = OpenAI()\n",
    "deepseek = OpenAI(api_key=deepseek_api_key, \n",
    "    base_url=\"https://api.deepseek.com\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# system prompt and user prompt  \n",
    " \n",
    "system_prompt = \"\"\"\n",
    "You're an entrepreneur focused on developing and investing in \n",
    "emerging AI-driven SaaS applications that solve critical pain\n",
    "points for small businesses—such as bookkeeping, reservations,\n",
    "tax preparation, and employee records management. \n",
    "\n",
    "You prioritize solutions leveraging agentic AI to address \n",
    "real-world business challenges with minimal human oversight,\n",
    "delivering both scalability and innovation. Your goal is to \n",
    "identify ideas with the highest potential for market disruption\n",
    "while helping small businesses save time and money.\n",
    "\n",
    "List all the business areas that might be worth exploring for \n",
    "Agentic AI.\n",
    "\n",
    "\"\"\"\n",
    "\n",
    "user_prompt = \"List all the business area that might be worth exploring for Agentic AI.\"\n",
    "\n",
    "messages = [\n",
    "    {\"role\": \"system\", \"content\":system_prompt},\n",
    "    {\"role\": \"user\", \"content\": user_prompt},\n",
    "]\n",
    "\n",
    "# Call openai\n",
    "response = deepseek.chat.completions.create(\n",
    "    model=\"deepseek-chat\",\n",
    "    messages=messages\n",
    ")\n",
    "\n",
    "business_ideas = response.choices[0].message.content\n",
    "display(Markdown(business_ideas))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Best idea prompt\n",
    "selected_idea_prompt = f\"\"\"Select the best idea from the list: {business_ideas} areas. \n",
    "Give reasons and why this pain point is the best to solve.\n",
    "List only the top idea.\"\"\"\n",
    "\n",
    "second_messages = [\n",
    "    {\"role\": \"system\", \"content\": system_prompt},\n",
    "    {\"role\": \"user\", \"content\": selected_idea_prompt}\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Call openai to select the best idea \n",
    "response = openai.chat.completions.create(\n",
    "    messages=second_messages,\n",
    "    model=\"gpt-4.1-mini\"\n",
    ")\n",
    "\n",
    "selected_idea = response.choices[0].message.content\n",
    "display(Markdown(selected_idea))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Add idea and pain points \n",
    "app['idea'] = selected_idea"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's create an app structure for the selected idea \n",
    "# Break the f-string into smaller parts for better readability and to avoid nesting issues\n",
    "system_prompt = \"Please create a react app file directory structure. You're given the business idea, along with the following pain points.\"\n",
    "structure_prompt = \"\"\"\n",
    "Respond in clear JSON format only, remove any backticks, extra spaces. The structure should also include \n",
    "frontend pages, authentication, api, stripe payment, and a backend database along with\n",
    "any necessary directories and files for the app to work without any errors.\n",
    "Respond with JSON format with name of the file, and path where the file should be stored, for example:\n",
    "\n",
    "{\n",
    "  \"root\": {\n",
    "    \"public\": {\n",
    "      \"index.html\": \"root/public/index.html\",\n",
    "      \"css\": {\n",
    "        \"style.css\": \"root/public/css/style.css\"\n",
    "      },\n",
    "      \"images\": {\n",
    "        \"logo.png\": \"root/public/images/logo.png\"\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "}\n",
    "\"\"\"\n",
    "\n",
    "create_structure_prompt = f\"{system_prompt}\\n{structure_prompt}\"\n",
    "\n",
    "structure_prompt= [\n",
    "    {\"role\": \"system\", \"content\": system_prompt},\n",
    "    {\"role\": \"user\", \"content\": create_structure_prompt}\n",
    "]\n",
    "\n",
    "response  = openai.chat.completions.create(\n",
    "    messages=structure_prompt,\n",
    "    model=\"gpt-4.1-mini\"    \n",
    ")\n",
    "structure = response.choices[0].message.content\n",
    "display(Markdown(structure))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "app[\"app_structure\"] =  structure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "structure_check_prompt = f\"\"\"You're a an expert react app developer. You validate \n",
    "react app file structure for the idea \n",
    "{selected_idea}\\n.\n",
    "If there're any errors with the structure, for example if there're missing files, directories, or any extra \n",
    "modifications needed to make the structure better, please respond \n",
    "with 'Needs modification' text/word only. \n",
    "\n",
    "If the structure doesn't need modification, simply \n",
    "respond with 'Correct structure' text/word only.\n",
    "\"\"\"\n",
    "\n",
    "structure_check= [\n",
    "    {\"role\": \"system\", \"content\": system_prompt},\n",
    "    {\"role\": \"user\", \"content\": structure_check_prompt}\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "We need to double check if the app structure is correct. We can use other models, \n",
    "deepseek seems to add extra files, and stays out of context, so let's stick with \n",
    "openai for now. \n",
    "\"\"\"\n",
    "response = deepseek.chat.completions.create(\n",
    "    messages=structure_check,\n",
    "    model=\"deepseek-chat\"  \n",
    ")\n",
    "\n",
    "double_check = response.choices[0].message.content\n",
    "display(Markdown(double_check))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check if the file structure is correct \n",
    "correct_structure = (double_check == 'Correct structure')\n",
    "\n",
    "if not correct_structure: # Only try if structure is incorrect \n",
    "    print(f\"Structure needs correction: {double_check}\")\n",
    "    max_count = 0\n",
    "    updated_structure = structure # Start with the original \n",
    "    \n",
    "    while max_count < 3 and not correct_structure:\n",
    "        \n",
    "        content = f\"\"\"Please correct the file structure {structure} for the selected idea \n",
    "        {selected_idea}. Respond with clear JSON format only, with no backticks.\"\"\"\n",
    "        json_format = f\"\"\"Please follow this example JSON structure:\n",
    "        If the structure is correct please respond with only 'Correct structure' text only.\"\"\"\n",
    "        example =\"\"\"\n",
    "        {\n",
    "            \"root\": {\n",
    "                \"public\": {\n",
    "                \"index.html\": \"root/public/index.html\",\n",
    "                \"css\": {\n",
    "                    \"style.css\": \"root/public/css/style.css\"\n",
    "                },\n",
    "                \"images\": {\n",
    "                    \"logo.png\": \"root/public/images/logo.png\"\n",
    "                }\n",
    "                }\n",
    "            }\n",
    "        }\n",
    "        \"\"\"\n",
    "        \n",
    "        retry_message = f\"{content}\\n {selected_idea}\\n{json_format}\\n{example}\"\n",
    "        \n",
    "        response = openai.chat.completions.create(\n",
    "        messages=[\n",
    "            {\"role\":\"system\", \"content\": system_prompt},\n",
    "            {\"role\": \"user\",\"content\": f\"{retry_message}\"}\n",
    "        ],\n",
    "        model=\"gpt-4.1-mini\"\n",
    "        )\n",
    "        \n",
    "        response = response.choices[0].message.content\n",
    "        \n",
    "        if response == 'Correct structure':\n",
    "            correct_structure = True\n",
    "            print(\"Structure is already correct, no modification needed.\")\n",
    "            \n",
    "        else:\n",
    "            # Retry\n",
    "            updated_structure = response \n",
    "            max_count += 1 \n",
    "            print(f\">>> Retrying...{max_count}\")\n",
    "    \n",
    "    # Update the app structure with the last/corrected version\n",
    "    app['app_structure'] = json.loads(updated_structure )\n",
    "    \n",
    "else:\n",
    "    print(\"Structure is already correct\")\n",
    "    app[\"app_structure\"] = json.loads(structure)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "app['app_structure']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Save as JSON file \n",
    "with open('app_structure.json', 'w') as f:\n",
    "    json.dump(app['app_structure'],f, indent=4)\n",
    "    \n",
    "    print(\"App structure saved to app_structure.json\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the file structure recursively, from structure in current directory\n",
    "def create_file_structure(structure: Dict, parent_dir:str='.'):\n",
    "    \"\"\"Create file structure recursively from structure. \"\"\"\n",
    "    try:\n",
    "        for file, folder in structure.items():\n",
    "            path = os.path.join(parent_dir, file)\n",
    "            if isinstance(folder, dict):\n",
    "                # It's a directory\n",
    "                os.makedirs(path, exist_ok=True)\n",
    "                create_file_structure(folder, path) # recursively create the sub folder structure\n",
    "            else:\n",
    "                # It's a file, create empty file\n",
    "                os.makedirs(parent_dir, exist_ok=True)\n",
    "                \n",
    "                # Check file extension\n",
    "                valid_extensions = ('.ts', '.tsx', '.md', '.js', '.css', '.json', '.jsx', '.html', '.txt', '.db', '.py', '.sql')\n",
    "                \n",
    "                if file.endswith(valid_extensions):\n",
    "                    with open(path, 'w') as f:\n",
    "                        pass  # Create an empty file\n",
    "                else:\n",
    "                    print(f'Unknown file type {file}')\n",
    "\n",
    "    except Exception as e:\n",
    "        print(f\"Error creating file structure: {e}\")\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Open the app_structure file \n",
    "filepath = os.path.join(os.getcwd(),'app_structure.json')\n",
    "\n",
    "with open(filepath, 'r', encoding='utf-8') as f:\n",
    "    app_structure = json.load(f) \n",
    "\n",
    "create_file_structure(app_structure, parent_dir='./app/')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "system_prompt = f\"\"\"You're Senior react developer with over 10 years of experience. \n",
    "\"\"\"\n",
    "user_prompt = f\"\"\"You're given the following app details in the {app['app_structure']}\\n\n",
    "for the {selected_idea}. Please write the following files . \n",
    "\n",
    "\"package.json\": \"root/package.json\"\n",
    "\"README.md\": \"root/README.md\"\n",
    "\".gitignore\": \"root/.gitignore\"\n",
    "\"webpack.config.js\": \"root/webpack.config.js\"\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "messages = [\n",
    "    {\"role\":\"system\", \"content\": system_prompt},\n",
    "    {\"role\": \"user\", \"content\": user_prompt}\n",
    "]\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    messages=messages,\n",
    "    model=\"gpt-4.1-mini\"\n",
    ")\n",
    "\n",
    "source_response = response.choices[0].message.content\n",
    "display(Markdown(source_response))\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}