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)
|