Lucas ARRIESSE
commited on
Commit
·
6edfd36
1
Parent(s):
c9e8a3f
Implement user insights
Browse files- app.py +1 -1
- doc/doc.md +21 -0
- prompts/private/assess.txt +1 -1
- prompts/private/extract.txt +3 -1
- prompts/private/refine.txt +3 -0
- static/index.html +11 -3
- static/js/gen.js +3 -1
- static/js/ui.js +4 -4
app.py
CHANGED
@@ -51,7 +51,7 @@ app.include_router(api.solutions.router, prefix="/solutions")
|
|
51 |
async def retrieve_prompt(task: str, prompt_env: Environment = Depends(get_prompt_templates)):
|
52 |
"""Retrieves a prompt for client-side private inference"""
|
53 |
try:
|
54 |
-
logging.
|
55 |
prompt, filename, _ = prompt_env.loader.get_source(
|
56 |
prompt_env, f"private/{task}.txt")
|
57 |
return prompt
|
|
|
51 |
async def retrieve_prompt(task: str, prompt_env: Environment = Depends(get_prompt_templates)):
|
52 |
"""Retrieves a prompt for client-side private inference"""
|
53 |
try:
|
54 |
+
logging.debug(f"Retrieving template for on device private task {task}.")
|
55 |
prompt, filename, _ = prompt_env.loader.get_source(
|
56 |
prompt_env, f"private/{task}.txt")
|
57 |
return prompt
|
doc/doc.md
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
## Reqxtract
|
3 |
+
|
4 |
+
The general use flow for the project is as follows
|
5 |
+
|
6 |
+
```mermaid
|
7 |
+
|
8 |
+
graph LR
|
9 |
+
RetrievingStep("Selecting pCRs from 3GPP meetings")
|
10 |
+
ExtractionStep("Extracting requirements from selected pCRs (server-side)")
|
11 |
+
GroupingStep("Group requirements together using a LLM (server-side)")
|
12 |
+
BootstrapSolutions("Boostrap solutions solving groups of requirements using a LLM (server-side)")
|
13 |
+
AssessAndRefineSolution("Assess idea for patentability against a virtual patent committee, and refine the idea iteratively (client-side).")
|
14 |
+
FindRelevantReqs("Find the requirements that are relevant to a given user idea / query")
|
15 |
+
|
16 |
+
RetrievingStep --> ExtractionStep
|
17 |
+
ExtractionStep --> FindRelevantReqs
|
18 |
+
ExtractionStep --> GroupingStep
|
19 |
+
GroupingStep --> BootstrapSolutions
|
20 |
+
BootstrapSolutions --> AssessAndRefineSolution
|
21 |
+
```
|
prompts/private/assess.txt
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
Patentability criteria are originality, innovative process, detectable,non-obvious by a person of the art, surprising.
|
5 |
Evaluate the patent using the following notation criterias while taking into account the business line and portfolio.
|
6 |
Finally end your analysis by stating whether the idea is a "NO-GO", "CONDITIONAL-GO", "IMMEDIATE-GO" and provide a list of actionnable insights.
|
7 |
-
The actionnable insights should be applicable directions to help refine the idea and align it better to the business portfolio (i.e, focus on a specific part of the idea instead of the whole idea, broaden up)
|
8 |
</task>
|
9 |
|
10 |
<business>
|
|
|
4 |
Patentability criteria are originality, innovative process, detectable,non-obvious by a person of the art, surprising.
|
5 |
Evaluate the patent using the following notation criterias while taking into account the business line and portfolio.
|
6 |
Finally end your analysis by stating whether the idea is a "NO-GO", "CONDITIONAL-GO", "IMMEDIATE-GO" and provide a list of actionnable insights.
|
7 |
+
The actionnable insights should be applicable directions to help refine the idea and align it better to the business portfolio (i.e, focus on a specific part of the idea instead of the whole idea, broaden up, split the idea into sub ideas)
|
8 |
</task>
|
9 |
|
10 |
<business>
|
prompts/private/extract.txt
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
<role>You are an useful assistant great at summarizing and extracting insight from reports</role>
|
2 |
-
<task>
|
|
|
3 |
and extract the actionnable insights.
|
|
|
4 |
</task>
|
5 |
|
6 |
<report>
|
|
|
1 |
<role>You are an useful assistant great at summarizing and extracting insight from reports</role>
|
2 |
+
<task>
|
3 |
+
Extract from the report you're given the final verdict for the evaluated idea ("NO-GO", "CONDITIONAL-GO", "IMMEDIATE-GO"), summarize the global report feedback
|
4 |
and extract the actionnable insights.
|
5 |
+
If an insight mentions splitting the idea into separate patents, reformulate it as Focus on the sub-idea, for each sub-idea the insight proposes.
|
6 |
</task>
|
7 |
|
8 |
<report>
|
prompts/private/refine.txt
CHANGED
@@ -18,6 +18,9 @@ Rewrite the whole idea while factoring in the refinements.
|
|
18 |
<insights>
|
19 |
Here are the insights:
|
20 |
{{insights}}
|
|
|
|
|
|
|
21 |
</insights>
|
22 |
|
23 |
<business>
|
|
|
18 |
<insights>
|
19 |
Here are the insights:
|
20 |
{{insights}}
|
21 |
+
|
22 |
+
Here is the aditionnal user insights the user has formulated:
|
23 |
+
{{user_insights}}
|
24 |
</insights>
|
25 |
|
26 |
<business>
|
static/index.html
CHANGED
@@ -364,9 +364,16 @@
|
|
364 |
<div id="insights-container" class="form-control mt-4 space-y-2">
|
365 |
<!-- Checkboxes will be dynamically inserted here -->
|
366 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
367 |
<div class="card-actions justify-end mt-6">
|
368 |
-
<button id="refine-btn" class="btn btn-primary">Refine
|
369 |
-
Insights</button>
|
370 |
</div>
|
371 |
</div>
|
372 |
</div>
|
@@ -457,7 +464,8 @@
|
|
457 |
</div>
|
458 |
<div class="mt-2 space-x-2">
|
459 |
<button class="btn btn-success" id="settings-save-btn">Save config</button>
|
460 |
-
<button class="btn btn-error absolute right-5" id="settings-clear-btn">Clear saved
|
|
|
461 |
</div>
|
462 |
</div>
|
463 |
</dialog>
|
|
|
364 |
<div id="insights-container" class="form-control mt-4 space-y-2">
|
365 |
<!-- Checkboxes will be dynamically inserted here -->
|
366 |
</div>
|
367 |
+
|
368 |
+
<!-- User insights-->
|
369 |
+
<div class="max-w space-y-2">
|
370 |
+
<p class="font-bold text-lg">User insights</p>
|
371 |
+
<p class="text-m text-base-content/70">You can provide here additional guidance for selected refinement insights above, or provide a customized additional insight.</p>
|
372 |
+
<textarea id="user-insight-text" class="textarea w-full" style="height: 197px;">
|
373 |
+
</textarea>
|
374 |
+
</div>
|
375 |
<div class="card-actions justify-end mt-6">
|
376 |
+
<button id="refine-btn" class="btn btn-primary">Refine draft</button>
|
|
|
377 |
</div>
|
378 |
</div>
|
379 |
</div>
|
|
|
464 |
</div>
|
465 |
<div class="mt-2 space-x-2">
|
466 |
<button class="btn btn-success" id="settings-save-btn">Save config</button>
|
467 |
+
<button class="btn btn-error absolute right-5" id="settings-clear-btn">Clear saved
|
468 |
+
configuration</button>
|
469 |
</div>
|
470 |
</div>
|
471 |
</dialog>
|
static/js/gen.js
CHANGED
@@ -187,6 +187,7 @@ export async function getModelList(providerUrl, apiKey) {
|
|
187 |
|
188 |
// # ========================================================================================== Idea assessment logic ==================================================================
|
189 |
|
|
|
190 |
// keep in sync with contents of "extract" prompt
|
191 |
const StructuredAssessmentOutput = zod.object({
|
192 |
final_verdict: zod.string(),
|
@@ -219,13 +220,14 @@ export async function assessSolution(providerUrl, modelName, apiKey, solution, a
|
|
219 |
return { assessment_full, extracted_info };
|
220 |
}
|
221 |
|
222 |
-
export async function refineSolution(providerUrl, modelName, apiKey, solution, insights, assessment_rules, portfolio_info) {
|
223 |
const template = await retrieveTemplate("refine");
|
224 |
|
225 |
const refine_template = formatTemplate(template, {
|
226 |
"problem_description": solution.problem_description,
|
227 |
"solution_description": solution.solution_description,
|
228 |
"insights": insights.join("\n -"),
|
|
|
229 |
"business_info": portfolio_info,
|
230 |
});
|
231 |
|
|
|
187 |
|
188 |
// # ========================================================================================== Idea assessment logic ==================================================================
|
189 |
|
190 |
+
// JS schema for the assessment output.
|
191 |
// keep in sync with contents of "extract" prompt
|
192 |
const StructuredAssessmentOutput = zod.object({
|
193 |
final_verdict: zod.string(),
|
|
|
220 |
return { assessment_full, extracted_info };
|
221 |
}
|
222 |
|
223 |
+
export async function refineSolution(providerUrl, modelName, apiKey, solution, insights, user_insights, assessment_rules, portfolio_info) {
|
224 |
const template = await retrieveTemplate("refine");
|
225 |
|
226 |
const refine_template = formatTemplate(template, {
|
227 |
"problem_description": solution.problem_description,
|
228 |
"solution_description": solution.solution_description,
|
229 |
"insights": insights.join("\n -"),
|
230 |
+
"user_insights": user_insights,
|
231 |
"business_info": portfolio_info,
|
232 |
});
|
233 |
|
static/js/ui.js
CHANGED
@@ -600,6 +600,7 @@ export function renderDraftUI() {
|
|
600 |
export function handleDraftRefine() {
|
601 |
// Fetch DOM elements here
|
602 |
const refineBtn = document.getElementById('refine-btn');
|
|
|
603 |
|
604 |
const currentState = draftHistory[draftCurrentIndex];
|
605 |
|
@@ -608,12 +609,11 @@ export function handleDraftRefine() {
|
|
608 |
.filter(i => i.checked)
|
609 |
.map(i => i.text);
|
610 |
|
611 |
-
if (selectedInsights.length === 0) {
|
612 |
-
alert('Please select at least one insight to refine the solution.');
|
613 |
return;
|
614 |
}
|
615 |
|
616 |
-
// --- THIS IS THE KEY LOGIC FOR INVALIDATING THE FUTURE ---
|
617 |
// If we are not at the end of the timeline, chop off the future states.
|
618 |
if (draftCurrentIndex < draftHistory.length - 1) {
|
619 |
draftHistory = draftHistory.slice(0, draftCurrentIndex + 1);
|
@@ -624,7 +624,7 @@ export function handleDraftRefine() {
|
|
624 |
|
625 |
showLoadingOverlay('Refining and assessing ....')
|
626 |
|
627 |
-
refineSolution(providerUrl, providerModel, providerToken, currentState.solution, selectedInsights, assessmentRules, businessPortfolio)
|
628 |
.then(newSolution => {
|
629 |
const refinedSolution = newSolution;
|
630 |
return assessSolution(providerUrl, providerModel, providerToken, newSolution, assessmentRules, businessPortfolio)
|
|
|
600 |
export function handleDraftRefine() {
|
601 |
// Fetch DOM elements here
|
602 |
const refineBtn = document.getElementById('refine-btn');
|
603 |
+
const userInsightsText = document.getElementById('user-insight-text').value;
|
604 |
|
605 |
const currentState = draftHistory[draftCurrentIndex];
|
606 |
|
|
|
609 |
.filter(i => i.checked)
|
610 |
.map(i => i.text);
|
611 |
|
612 |
+
if (selectedInsights.length === 0 && (userInsightsText === null || userInsightsText === "")) {
|
613 |
+
alert('Please select at least one insight to refine the solution or provide a manual user insight.');
|
614 |
return;
|
615 |
}
|
616 |
|
|
|
617 |
// If we are not at the end of the timeline, chop off the future states.
|
618 |
if (draftCurrentIndex < draftHistory.length - 1) {
|
619 |
draftHistory = draftHistory.slice(0, draftCurrentIndex + 1);
|
|
|
624 |
|
625 |
showLoadingOverlay('Refining and assessing ....')
|
626 |
|
627 |
+
refineSolution(providerUrl, providerModel, providerToken, currentState.solution, selectedInsights, userInsightsText, assessmentRules, businessPortfolio)
|
628 |
.then(newSolution => {
|
629 |
const refinedSolution = newSolution;
|
630 |
return assessSolution(providerUrl, providerModel, providerToken, newSolution, assessmentRules, businessPortfolio)
|