Spaces:
Sleeping
Sleeping
Lucas ARRIESSE
commited on
Commit
·
46d8b46
1
Parent(s):
f6bffda
Remove old endpoints
Browse files
api/solutions.py
CHANGED
|
@@ -7,13 +7,13 @@ from jinja2 import Environment
|
|
| 7 |
from litellm.router import Router
|
| 8 |
from dependencies import INSIGHT_FINDER_BASE_URL, get_http_client, get_llm_router, get_prompt_templates
|
| 9 |
from typing import Awaitable, Callable, TypeVar
|
| 10 |
-
from schemas import _RefinedSolutionModel,
|
| 11 |
|
| 12 |
# Router for solution generation and critique
|
| 13 |
router = APIRouter(tags=["solution generation and critique"])
|
| 14 |
|
| 15 |
|
| 16 |
-
# ============== utilities
|
| 17 |
T = TypeVar("T")
|
| 18 |
A = TypeVar("A")
|
| 19 |
|
|
@@ -32,68 +32,65 @@ async def retry_until(
|
|
| 32 |
last_value = await func(arg)
|
| 33 |
return last_value
|
| 34 |
|
| 35 |
-
#
|
| 36 |
|
|
|
|
|
|
|
| 37 |
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
req_prompt = await prompt_env.get_template("search_solution_v2.txt").render_async(**{
|
| 47 |
-
"category": cat.model_dump(),
|
| 48 |
-
"user_constraints": params.user_constraints,
|
| 49 |
-
})
|
| 50 |
|
| 51 |
-
#
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
req_completion = await llm_router.acompletion(model="gemini-v2", messages=[
|
| 55 |
-
{"role": "user", "content": req_prompt}
|
| 56 |
-
], tools=[{"googleSearch": {}}], tool_choice="required")
|
| 57 |
|
| 58 |
-
#
|
|
|
|
|
|
|
| 59 |
|
| 60 |
-
|
| 61 |
-
"solution": req_completion.choices[0].message.content,
|
| 62 |
-
"response_schema": _SearchedSolutionModel.model_json_schema()
|
| 63 |
-
})
|
| 64 |
|
| 65 |
-
|
| 66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
], response_format=_SearchedSolutionModel)
|
| 68 |
-
solution_model = _SearchedSolutionModel.model_validate_json(
|
| 69 |
-
structured_completion.choices[0].message.content)
|
| 70 |
-
|
| 71 |
-
# ======================== build the final solution object ================================
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
try:
|
| 76 |
-
sources_metadata.extend([{"name": a["web"]["title"], "url": a["web"]["uri"]}
|
| 77 |
-
for a in req_completion["vertex_ai_grounding_metadata"][0]['groundingChunks']])
|
| 78 |
-
except KeyError as ke:
|
| 79 |
-
pass
|
| 80 |
|
| 81 |
-
|
| 82 |
Context="",
|
| 83 |
Requirements=[
|
| 84 |
-
cat.requirements[i].requirement for i in
|
| 85 |
],
|
| 86 |
-
Problem_Description=
|
| 87 |
-
Solution_Description=
|
| 88 |
-
References=
|
| 89 |
Category_Id=cat.id,
|
| 90 |
)
|
| 91 |
-
return final_sol
|
| 92 |
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
| 97 |
|
| 98 |
return SolutionSearchResponse(solutions=final_solutions)
|
| 99 |
|
|
@@ -155,65 +152,3 @@ async def refine_solutions(params: CritiqueResponse, prompt_env: Environment = D
|
|
| 155 |
|
| 156 |
return SolutionSearchResponse(solutions=refined_solutions)
|
| 157 |
|
| 158 |
-
# =============================================================== Search solutions =========================================
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
@router.post("/search_solutions_if")
|
| 162 |
-
async def search_solutions_if(req: SolutionSearchV2Request, prompt_env: Environment = Depends(get_prompt_templates), llm_router: Router = Depends(get_llm_router), http_client: AsyncClient = Depends(get_http_client)) -> SolutionSearchResponse:
|
| 163 |
-
|
| 164 |
-
async def _search_solution_inner(cat: ReqGroupingCategory):
|
| 165 |
-
# process requirements into insight finder format
|
| 166 |
-
fmt_completion = await llm_router.acompletion("gemini-v2", messages=[
|
| 167 |
-
{
|
| 168 |
-
"role": "user",
|
| 169 |
-
"content": await prompt_env.get_template("if/format_requirements.txt").render_async(**{
|
| 170 |
-
"category": cat.model_dump(),
|
| 171 |
-
"response_schema": InsightFinderConstraintsList.model_json_schema()
|
| 172 |
-
})
|
| 173 |
-
}], response_format=InsightFinderConstraintsList)
|
| 174 |
-
|
| 175 |
-
fmt_model = InsightFinderConstraintsList.model_validate_json(
|
| 176 |
-
fmt_completion.choices[0].message.content)
|
| 177 |
-
|
| 178 |
-
# translate from a structured output to a dict for insights finder
|
| 179 |
-
formatted_constraints = {'constraints': {
|
| 180 |
-
cons.title: cons.description for cons in fmt_model.constraints}}
|
| 181 |
-
|
| 182 |
-
# fetch technologies from insight finder
|
| 183 |
-
technologies_req = await http_client.post(INSIGHT_FINDER_BASE_URL + "process-constraints", content=json.dumps(formatted_constraints))
|
| 184 |
-
technologies = TechnologyData.model_validate(technologies_req.json())
|
| 185 |
-
|
| 186 |
-
# =============================================================== synthesize solution using LLM =========================================
|
| 187 |
-
|
| 188 |
-
format_solution = await llm_router.acompletion("gemini-v2", messages=[{
|
| 189 |
-
"role": "user",
|
| 190 |
-
"content": await prompt_env.get_template("if/synthesize_solution.txt").render_async(**{
|
| 191 |
-
"category": cat.model_dump(),
|
| 192 |
-
"technologies": technologies.model_dump()["technologies"],
|
| 193 |
-
"user_constraints": req.user_constraints,
|
| 194 |
-
"response_schema": _SearchedSolutionModel.model_json_schema()
|
| 195 |
-
})}
|
| 196 |
-
], response_format=_SearchedSolutionModel)
|
| 197 |
-
|
| 198 |
-
format_solution_model = _SearchedSolutionModel.model_validate_json(
|
| 199 |
-
format_solution.choices[0].message.content)
|
| 200 |
-
|
| 201 |
-
final_solution = SolutionModel(
|
| 202 |
-
Context="",
|
| 203 |
-
Requirements=[
|
| 204 |
-
cat.requirements[i].requirement for i in format_solution_model.requirement_ids
|
| 205 |
-
],
|
| 206 |
-
Problem_Description=format_solution_model.problem_description,
|
| 207 |
-
Solution_Description=format_solution_model.solution_description,
|
| 208 |
-
References=[],
|
| 209 |
-
Category_Id=cat.id,
|
| 210 |
-
)
|
| 211 |
-
|
| 212 |
-
# ========================================================================================================================================
|
| 213 |
-
|
| 214 |
-
return final_solution
|
| 215 |
-
|
| 216 |
-
tasks = await asyncio.gather(*[_search_solution_inner(cat) for cat in req.categories], return_exceptions=True)
|
| 217 |
-
final_solutions = [sol for sol in tasks if not isinstance(sol, Exception)]
|
| 218 |
-
|
| 219 |
-
return SolutionSearchResponse(solutions=final_solutions)
|
|
|
|
| 7 |
from litellm.router import Router
|
| 8 |
from dependencies import INSIGHT_FINDER_BASE_URL, get_http_client, get_llm_router, get_prompt_templates
|
| 9 |
from typing import Awaitable, Callable, TypeVar
|
| 10 |
+
from schemas import _RefinedSolutionModel, _SearchedSolutionModel, _SolutionCriticismOutput, CriticizeSolutionsRequest, CritiqueResponse, InsightFinderConstraintsList, ReqGroupingCategory, ReqGroupingRequest, ReqGroupingResponse, ReqSearchLLMResponse, ReqSearchRequest, ReqSearchResponse, SolutionCriticism, SolutionModel, SolutionSearchResponse, SolutionSearchV2Request, TechnologyData
|
| 11 |
|
| 12 |
# Router for solution generation and critique
|
| 13 |
router = APIRouter(tags=["solution generation and critique"])
|
| 14 |
|
| 15 |
|
| 16 |
+
# ============== utilities ===========================
|
| 17 |
T = TypeVar("T")
|
| 18 |
A = TypeVar("A")
|
| 19 |
|
|
|
|
| 32 |
last_value = await func(arg)
|
| 33 |
return last_value
|
| 34 |
|
| 35 |
+
# =================================================== Search solutions ============================================================================
|
| 36 |
|
| 37 |
+
@router.post("/search_solutions")
|
| 38 |
+
async def search_solutions_if(req: SolutionSearchV2Request, prompt_env: Environment = Depends(get_prompt_templates), llm_router: Router = Depends(get_llm_router), http_client: AsyncClient = Depends(get_http_client)) -> SolutionSearchResponse:
|
| 39 |
|
| 40 |
+
async def _search_solution_inner(cat: ReqGroupingCategory):
|
| 41 |
+
# process requirements into insight finder format
|
| 42 |
+
fmt_completion = await llm_router.acompletion("gemini-v2", messages=[
|
| 43 |
+
{
|
| 44 |
+
"role": "user",
|
| 45 |
+
"content": await prompt_env.get_template("format_requirements.txt").render_async(**{
|
| 46 |
+
"category": cat.model_dump(),
|
| 47 |
+
"response_schema": InsightFinderConstraintsList.model_json_schema()
|
| 48 |
+
})
|
| 49 |
+
}], response_format=InsightFinderConstraintsList)
|
| 50 |
|
| 51 |
+
fmt_model = InsightFinderConstraintsList.model_validate_json(
|
| 52 |
+
fmt_completion.choices[0].message.content)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
|
| 54 |
+
# translate from a structured output to a dict for insights finder
|
| 55 |
+
formatted_constraints = {'constraints': {
|
| 56 |
+
cons.title: cons.description for cons in fmt_model.constraints}}
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
+
# fetch technologies from insight finder
|
| 59 |
+
technologies_req = await http_client.post(INSIGHT_FINDER_BASE_URL + "process-constraints", content=json.dumps(formatted_constraints))
|
| 60 |
+
technologies = TechnologyData.model_validate(technologies_req.json())
|
| 61 |
|
| 62 |
+
# =============================================================== synthesize solution using LLM =========================================
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
+
format_solution = await llm_router.acompletion("gemini-v2", messages=[{
|
| 65 |
+
"role": "user",
|
| 66 |
+
"content": await prompt_env.get_template("synthesize_solution.txt").render_async(**{
|
| 67 |
+
"category": cat.model_dump(),
|
| 68 |
+
"technologies": technologies.model_dump()["technologies"],
|
| 69 |
+
"user_constraints": req.user_constraints,
|
| 70 |
+
"response_schema": _SearchedSolutionModel.model_json_schema()
|
| 71 |
+
})}
|
| 72 |
], response_format=_SearchedSolutionModel)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
+
format_solution_model = _SearchedSolutionModel.model_validate_json(
|
| 75 |
+
format_solution.choices[0].message.content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
+
final_solution = SolutionModel(
|
| 78 |
Context="",
|
| 79 |
Requirements=[
|
| 80 |
+
cat.requirements[i].requirement for i in format_solution_model.requirement_ids
|
| 81 |
],
|
| 82 |
+
Problem_Description=format_solution_model.problem_description,
|
| 83 |
+
Solution_Description=format_solution_model.solution_description,
|
| 84 |
+
References=[],
|
| 85 |
Category_Id=cat.id,
|
| 86 |
)
|
|
|
|
| 87 |
|
| 88 |
+
# ========================================================================================================================================
|
| 89 |
+
|
| 90 |
+
return final_solution
|
| 91 |
+
|
| 92 |
+
tasks = await asyncio.gather(*[_search_solution_inner(cat) for cat in req.categories], return_exceptions=True)
|
| 93 |
+
final_solutions = [sol for sol in tasks if not isinstance(sol, Exception)]
|
| 94 |
|
| 95 |
return SolutionSearchResponse(solutions=final_solutions)
|
| 96 |
|
|
|
|
| 152 |
|
| 153 |
return SolutionSearchResponse(solutions=refined_solutions)
|
| 154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
prompts/{if/format_requirements.txt → format_requirements.txt}
RENAMED
|
File without changes
|
prompts/search_solution.txt
DELETED
|
@@ -1,23 +0,0 @@
|
|
| 1 |
-
<role>You are an expert system designer</role>
|
| 2 |
-
<task>
|
| 3 |
-
Your task is to create a solution that should cover the maximum possible of requirements at once.
|
| 4 |
-
The solution should be composed of multiple mechanisms, that are defined as processes, methods, or sequences of steps using a technology that explain how something works or achieves its requirements.
|
| 5 |
-
You may for that search mechanisms for the different requirements.
|
| 6 |
-
**Please actually make searches and do not simulate them.**
|
| 7 |
-
|
| 8 |
-
You must aim for the following goals:
|
| 9 |
-
- The solution must aim to maximize requirement satisfaction while respecting the context.
|
| 10 |
-
- Provide a list of requirements addressed by the solution (provide only the requirement IDs)
|
| 11 |
-
- Please also detail each mechanism and how they work in the final solution description.
|
| 12 |
-
- Please describe the solution description using markdown in a consistent format.
|
| 13 |
-
</task>
|
| 14 |
-
|
| 15 |
-
Here is the category item and the associated requirements:
|
| 16 |
-
<requirements>
|
| 17 |
-
Category Title: {{category["title"]}}
|
| 18 |
-
Context: {{category["requirements"][0]["context"]}}
|
| 19 |
-
Requirements:
|
| 20 |
-
{% for req in category["requirements"] -%}
|
| 21 |
-
- {{loop.index0}} {{req["requirement"]}}
|
| 22 |
-
{% endfor -%}
|
| 23 |
-
</requirements>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
prompts/search_solution_v2.txt
DELETED
|
@@ -1,31 +0,0 @@
|
|
| 1 |
-
<role>You are an expert system designer</role>
|
| 2 |
-
<task>
|
| 3 |
-
Your task is to create a solution that should cover the maximum possible of requirements at once.
|
| 4 |
-
The solution should be composed of multiple mechanisms, that are defined as processes, methods, or sequences of steps using a technology that explain how something works or achieves its requirements.
|
| 5 |
-
You may for that search mechanisms for the different requirements.
|
| 6 |
-
|
| 7 |
-
**Please actually make searches and do not simulate them.**
|
| 8 |
-
|
| 9 |
-
You must aim for the following goals:
|
| 10 |
-
- The solution must aim to maximize requirement satisfaction while respecting the context.
|
| 11 |
-
- Provide a list of requirements addressed by the solution (provide only the requirement IDs)
|
| 12 |
-
- Please also detail each mechanism and how they work in the final solution description.
|
| 13 |
-
- Please describe the solution description using markdown in a consistent format.
|
| 14 |
-
</task>
|
| 15 |
-
|
| 16 |
-
Here is the category item and the associated requirements:
|
| 17 |
-
<requirements>
|
| 18 |
-
Category Title: {{category["title"]}}
|
| 19 |
-
Context: {{category["requirements"][0]["context"]}}
|
| 20 |
-
Requirements:
|
| 21 |
-
{% for req in category["requirements"] -%}
|
| 22 |
-
- {{loop.index0}} {{req["requirement"]}}
|
| 23 |
-
{% endfor -%}
|
| 24 |
-
</requirements>
|
| 25 |
-
|
| 26 |
-
{% if user_constraints is not none %}
|
| 27 |
-
Here are additional user constraints the solution must respect:
|
| 28 |
-
<user_constraints>
|
| 29 |
-
{{user_constraints}}
|
| 30 |
-
</user_constraints>
|
| 31 |
-
{% endif %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
prompts/{if/synthesize_solution.txt → synthesize_solution.txt}
RENAMED
|
File without changes
|
static/index.html
CHANGED
|
@@ -270,7 +270,7 @@
|
|
| 270 |
Categorize
|
| 271 |
</button>
|
| 272 |
</div>
|
| 273 |
-
<div class="flex flex-wrap justify-end items-center gap-6">
|
| 274 |
<div class="tooltip" data-tip="Use Insight Finder's API to generate solutions">
|
| 275 |
<label class="label">
|
| 276 |
<span class="label-text text-base-content">Use insight finder solver</span>
|
|
@@ -278,7 +278,7 @@
|
|
| 278 |
<input type="checkbox" class="toggle toggle-primary" id="use-insight-finder-solver"
|
| 279 |
checked="false" />
|
| 280 |
</div>
|
| 281 |
-
</div>
|
| 282 |
</div>
|
| 283 |
<div id="categorized-requirements-container pt-10" class="mb-6">
|
| 284 |
<div class="flex mb-4 pt-10">
|
|
|
|
| 270 |
Categorize
|
| 271 |
</button>
|
| 272 |
</div>
|
| 273 |
+
<!-- <div class="flex flex-wrap justify-end items-center gap-6">
|
| 274 |
<div class="tooltip" data-tip="Use Insight Finder's API to generate solutions">
|
| 275 |
<label class="label">
|
| 276 |
<span class="label-text text-base-content">Use insight finder solver</span>
|
|
|
|
| 278 |
<input type="checkbox" class="toggle toggle-primary" id="use-insight-finder-solver"
|
| 279 |
checked="false" />
|
| 280 |
</div>
|
| 281 |
+
</div> -->
|
| 282 |
</div>
|
| 283 |
<div id="categorized-requirements-container pt-10" class="mb-6">
|
| 284 |
<div class="flex mb-4 pt-10">
|
static/js/script.js
CHANGED
|
@@ -335,13 +335,6 @@ async function extractRequirements() {
|
|
| 335 |
}
|
| 336 |
});
|
| 337 |
|
| 338 |
-
|
| 339 |
-
// const response = await fetch('/generate_requirements/', {
|
| 340 |
-
// method: 'POST',
|
| 341 |
-
// headers: { 'Content-Type': 'application/json' },
|
| 342 |
-
// body: req
|
| 343 |
-
// });
|
| 344 |
-
|
| 345 |
const data = response.data; // data in the SSE message contains the requirements response
|
| 346 |
requirements = data.requirements;
|
| 347 |
let req_id = 0;
|
|
@@ -1047,33 +1040,30 @@ function clearAllSolutions() {
|
|
| 1047 |
document.querySelectorAll('.solution-accordion').forEach(a => a.remove());
|
| 1048 |
}
|
| 1049 |
|
| 1050 |
-
async function
|
| 1051 |
console.log(selected_categories);
|
| 1052 |
|
| 1053 |
let input_req = structuredClone(selected_categories);
|
| 1054 |
input_req.user_constraints = user_constraints;
|
| 1055 |
-
console.log(useIFSolver);
|
| 1056 |
-
|
| 1057 |
-
const base_url = useIFSolver ? "/solutions/search_solutions_if" : "/solutions/search_solutions_gemini/v2"
|
| 1058 |
|
| 1059 |
-
let response = await fetch(
|
| 1060 |
let responseObj = await response.json()
|
| 1061 |
return responseObj;
|
| 1062 |
}
|
| 1063 |
|
| 1064 |
-
async function
|
| 1065 |
let response = await fetch('/solutions/criticize_solution', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(solutions) })
|
| 1066 |
let responseObj = await response.json()
|
| 1067 |
solutionsCriticizedVersions.push(responseObj)
|
| 1068 |
}
|
| 1069 |
|
| 1070 |
-
async function
|
| 1071 |
let response = await fetch('/solutions/refine_solutions', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(critiques) })
|
| 1072 |
let responseObj = await response.json()
|
| 1073 |
-
await
|
| 1074 |
}
|
| 1075 |
|
| 1076 |
-
async function workflow(steps = 1
|
| 1077 |
let soluce;
|
| 1078 |
showLoadingOverlay('Génération des solutions & critiques ....');
|
| 1079 |
|
|
@@ -1093,11 +1083,11 @@ async function workflow(steps = 1, useIFSolver = false) {
|
|
| 1093 |
}
|
| 1094 |
|
| 1095 |
if (solutionsCriticizedVersions.length == 0) {
|
| 1096 |
-
soluce = await
|
| 1097 |
-
await
|
| 1098 |
} else {
|
| 1099 |
let prevSoluce = solutionsCriticizedVersions[solutionsCriticizedVersions.length - 1];
|
| 1100 |
-
await
|
| 1101 |
}
|
| 1102 |
}
|
| 1103 |
hideLoadingOverlay();
|
|
@@ -1129,10 +1119,10 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
| 1129 |
// Événements pour les boutons de solutions (à implémenter plus tard)
|
| 1130 |
document.getElementById('get-solutions-btn').addEventListener('click', () => {
|
| 1131 |
const n_steps = document.getElementById('solution-gen-nsteps').value;
|
| 1132 |
-
workflow(n_steps
|
| 1133 |
});
|
| 1134 |
-
|
| 1135 |
-
workflow(1
|
| 1136 |
});
|
| 1137 |
});
|
| 1138 |
|
|
|
|
| 335 |
}
|
| 336 |
});
|
| 337 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 338 |
const data = response.data; // data in the SSE message contains the requirements response
|
| 339 |
requirements = data.requirements;
|
| 340 |
let req_id = 0;
|
|
|
|
| 1040 |
document.querySelectorAll('.solution-accordion').forEach(a => a.remove());
|
| 1041 |
}
|
| 1042 |
|
| 1043 |
+
async function generateSolutions(selected_categories, user_constraints = null) {
|
| 1044 |
console.log(selected_categories);
|
| 1045 |
|
| 1046 |
let input_req = structuredClone(selected_categories);
|
| 1047 |
input_req.user_constraints = user_constraints;
|
|
|
|
|
|
|
|
|
|
| 1048 |
|
| 1049 |
+
let response = await fetch("/solutions/search_solutions", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(input_req) })
|
| 1050 |
let responseObj = await response.json()
|
| 1051 |
return responseObj;
|
| 1052 |
}
|
| 1053 |
|
| 1054 |
+
async function generateCriticisms(solutions) {
|
| 1055 |
let response = await fetch('/solutions/criticize_solution', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(solutions) })
|
| 1056 |
let responseObj = await response.json()
|
| 1057 |
solutionsCriticizedVersions.push(responseObj)
|
| 1058 |
}
|
| 1059 |
|
| 1060 |
+
async function refineSolutions(critiques) {
|
| 1061 |
let response = await fetch('/solutions/refine_solutions', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(critiques) })
|
| 1062 |
let responseObj = await response.json()
|
| 1063 |
+
await generateCriticisms(responseObj)
|
| 1064 |
}
|
| 1065 |
|
| 1066 |
+
async function workflow(steps = 1) {
|
| 1067 |
let soluce;
|
| 1068 |
showLoadingOverlay('Génération des solutions & critiques ....');
|
| 1069 |
|
|
|
|
| 1083 |
}
|
| 1084 |
|
| 1085 |
if (solutionsCriticizedVersions.length == 0) {
|
| 1086 |
+
soluce = await generateSolutions(selected_requirements, user_constraints ? user_constraints : null);
|
| 1087 |
+
await generateCriticisms(soluce)
|
| 1088 |
} else {
|
| 1089 |
let prevSoluce = solutionsCriticizedVersions[solutionsCriticizedVersions.length - 1];
|
| 1090 |
+
await refineSolutions(prevSoluce)
|
| 1091 |
}
|
| 1092 |
}
|
| 1093 |
hideLoadingOverlay();
|
|
|
|
| 1119 |
// Événements pour les boutons de solutions (à implémenter plus tard)
|
| 1120 |
document.getElementById('get-solutions-btn').addEventListener('click', () => {
|
| 1121 |
const n_steps = document.getElementById('solution-gen-nsteps').value;
|
| 1122 |
+
workflow(n_steps);
|
| 1123 |
});
|
| 1124 |
+
document.getElementById('get-solutions-step-btn').addEventListener('click', () => {
|
| 1125 |
+
workflow(1);
|
| 1126 |
});
|
| 1127 |
});
|
| 1128 |
|