YchKhan commited on
Commit
0ef5d6d
·
verified ·
1 Parent(s): df74b3d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -2
app.py CHANGED
@@ -1,7 +1,163 @@
1
- from fastapi import FastAPI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  app = FastAPI()
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  @app.get("/")
6
  def greet_json():
7
- return {"Hello": "World!"}
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.responses import JSONResponse
3
+ from pydantic import BaseModel, Field
4
+ from typing import List, Optional
5
+ import os
6
+ import json
7
+
8
+ # ---- Requirements Models ----
9
+
10
+ class RequirementInfo(BaseModel):
11
+ """Represents an extracted requirement info."""
12
+ context: str = Field(..., description="Context for the requirement.")
13
+ requirement: str = Field(..., description="The requirement itself.")
14
+ document: Optional[str] = Field('', description="The document the requirement is extracted from.")
15
+
16
+ class ReqGroupingCategory(BaseModel):
17
+ """Represents the category of requirements grouped together."""
18
+ id: int = Field(..., description="ID of the grouping category")
19
+ title: str = Field(..., description="Title given to the grouping category")
20
+ requirements: List[RequirementInfo] = Field(
21
+ ..., description="List of grouped requirements")
22
+
23
+ class ReqGroupingResponse(BaseModel):
24
+ categories: List[ReqGroupingCategory]
25
+
26
+
27
+ # ---- Solution Models ----
28
+
29
+ class SolutionModel(BaseModel):
30
+ Context: str = Field(..., description="Full context provided for this category.")
31
+ Requirements: List[str] = Field(..., description="List of each requirement as string.")
32
+ Problem_Description: str = Field(..., alias="Problem Description",
33
+ description="Description of the problem being solved.")
34
+ Solution_Description: str = Field(..., alias="Solution Description",
35
+ description="Detailed description of the solution.")
36
+ References: Optional[str] = Field('', description="References to documents used for the solution.")
37
+
38
+ class Config:
39
+ allow_population_by_field_name = True # Enables alias handling on input/output
40
+
41
+ class SolutionsResponse(BaseModel):
42
+ solutions: List[SolutionModel]
43
+
44
+
45
+ # ---- FastAPI app ----
46
 
47
  app = FastAPI()
48
 
49
+
50
+ # ---- LLM Integration ----
51
+
52
+ def ask_llm(user_message, model='compound-beta', system_prompt="You are a helpful assistant"):
53
+ from groq import Groq # Import here so the app starts without the module if needed
54
+ client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
55
+
56
+ response = client.chat.completions.create(
57
+ model=model,
58
+ messages=[
59
+ {
60
+ "role": "system",
61
+ "content": system_prompt
62
+ },
63
+ {
64
+ "role": "user",
65
+ "content": user_message
66
+ }
67
+ ],
68
+ stream=False,
69
+ )
70
+ ai_reply = response.choices[0].message.content
71
+ return ai_reply
72
+
73
+ solution_prompt = """You are an expert system designer. Your task is to find a solution that addresses as many of the provided requirements as possible, while carefully considering the given context. Browse internet for reliable sources.
74
+
75
+ Respond strictly in the following JSON format:
76
+
77
+ {
78
+ "Context": "<Insert the full context provided for this category>",
79
+ "Requirements": [
80
+ "<List each requirement clearly as a string item>"
81
+ ],
82
+ "Problem Description": "<Describe the problem the solution is solving without introducing it>",
83
+ "Solution Description": "<Explain the proposed solution, detailing how it meets each of the specified requirements and aligns with the given context. Prioritize completeness and practicality.>",
84
+ "References": "<The references to the documents used to write the solution>"
85
+ }
86
+
87
+ text
88
+ ⚠️ Rules:
89
+
90
+ Do not omit any part of the JSON structure.
91
+
92
+ Replace newline characters with \"\\n\" (double backslash-n for JSON)
93
+
94
+ Ensure all fields are present, even if empty.
95
+
96
+ The solution must aim to maximize requirement satisfaction while respecting the context.
97
+
98
+ Provide a clear and well-reasoned description of how your solution addresses each requirement.
99
+ """
100
+
101
+ # ---- Main Endpoint ----
102
+
103
+ @app.post("/find_solutions", response_model=SolutionsResponse)
104
+ async def find_solutions(requirements: ReqGroupingResponse):
105
+ solutions = []
106
+
107
+ for category in requirements.categories:
108
+ category_title = category.title
109
+ category_requirements = category.requirements
110
+
111
+ # Compose the LLM prompt
112
+ problem_description = solution_prompt
113
+ problem_description += f"Category title: {category_title}\n"
114
+
115
+ context_list = []
116
+ requirement_list = []
117
+ for req_item in category_requirements:
118
+ context_list.append(f"- Context: {req_item.context}")
119
+ requirement_list.append(f"- Requirement: {req_item.requirement}")
120
+
121
+ problem_description += "Contexts:\n" + "\n".join(context_list) + "\n\n"
122
+ problem_description += "Requirements:\n" + "\n".join(requirement_list)
123
+
124
+ llm_response = ask_llm(problem_description)
125
+ print(f"Solution for '{category_title}' category:")
126
+ print(llm_response)
127
+
128
+ # Clean and parse the LLM response
129
+ try:
130
+ # Remove code blocks if present
131
+ cleaned = llm_response.strip()
132
+ if cleaned.startswith('```
133
+ cleaned = cleaned[7:]
134
+ if cleaned.startswith('```'):
135
+ cleaned = cleaned[3:]
136
+ if cleaned.endswith('```
137
+ cleaned = cleaned[:-3]
138
+ cleaned = cleaned.strip()
139
+
140
+ # Replace double backslashes with single if needed for parsing
141
+ cleaned = cleaned.replace('\\\\n', '\\n')
142
+ parsed = json.loads(cleaned)
143
+
144
+ # Use alias-aware population for SolutionModel
145
+ solution_obj = SolutionModel.parse_obj(parsed)
146
+ solutions.append(solution_obj)
147
+ except Exception as e:
148
+ # Append error info as a solution model (helps debug)
149
+ error_solution = SolutionModel(
150
+ Context="",
151
+ Requirements=[],
152
+ Problem_Description=f"Failed to parse LLM response: {str(e)}",
153
+ Solution_Description=f"Original LLM output: {llm_response}",
154
+ References=""
155
+ )
156
+ solutions.append(error_solution)
157
+
158
+ return SolutionsResponse(solutions=solutions)
159
+
160
+
161
  @app.get("/")
162
  def greet_json():
163
+ return {"Status": "OK!"}