|
import zod from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm' |
|
|
|
|
|
|
|
|
|
|
|
|
|
export function formatTemplate(template, args) { |
|
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => { |
|
|
|
|
|
|
|
if (key in args) |
|
return args[key]; |
|
|
|
|
|
return ""; |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
export async function retrieveTemplate(task) { |
|
const req = await fetch(`/prompt/${task}`) |
|
return await req.text(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
export async function performDeepSearch(topics) { |
|
const response = await fetch('/solutions/search_prior_art', { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/json' }, |
|
body: JSON.stringify({ topics: topics }) |
|
}); |
|
const results = await response.json(); |
|
return results.content; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function generateCompletion(providerUrl, modelName, apiKey, messages, temperature = 0.5) { |
|
const genEndpoint = providerUrl + "/chat/completions" |
|
|
|
try { |
|
const response = await fetch(genEndpoint, { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
'Authorization': `Bearer ${apiKey}`, |
|
}, |
|
body: JSON.stringify({ |
|
model: modelName, |
|
messages: messages, |
|
temperature: temperature, |
|
}), |
|
}); |
|
|
|
if (!response.ok) { |
|
const errorData = await response.json(); |
|
throw new Error(`API request failed with status ${response.status}: ${errorData.error?.message || 'Unknown error'}`); |
|
} |
|
|
|
const data = await response.json(); |
|
|
|
if (data.choices && data.choices.length > 0 && data.choices[0].message && data.choices[0].message.content) |
|
return data.choices[0].message.content; |
|
|
|
} catch (error) { |
|
console.error("Error calling private LLM :", error); |
|
throw error; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function generateStructuredCompletion(providerUrl, modelName, apiKey, messages, schema, temperature = 0.5) { |
|
const genEndpoint = providerUrl + "/chat/completions"; |
|
try { |
|
const response = await fetch(genEndpoint, { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
'Authorization': `Bearer ${apiKey}`, |
|
}, |
|
body: JSON.stringify({ |
|
model: modelName, |
|
messages: messages, |
|
temperature: temperature, |
|
response_format: { type: "json_object" } |
|
}), |
|
}); |
|
|
|
if (!response.ok) { |
|
const errorData = await response.json(); |
|
throw new Error(`API request failed with status ${response.status}: ${errorData.error?.message || 'Unknown error'}`); |
|
} |
|
|
|
const data = await response.json(); |
|
|
|
console.log(data.choices[0].message.content); |
|
|
|
|
|
const parsedJSON = JSON.parse(data.choices[0].message.content.replace('```json', '').replace("```", "")); |
|
|
|
|
|
const validatedSchema = schema.parse(parsedJSON); |
|
|
|
return validatedSchema; |
|
} catch (error) { |
|
console.error("Error calling private LLM :", error); |
|
throw error; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function getModelList(providerUrl, apiKey) { |
|
try { |
|
|
|
const modelsUrl = `${providerUrl}/models`; |
|
|
|
console.log(modelsUrl); |
|
|
|
|
|
const response = await fetch(modelsUrl, { |
|
method: 'GET', |
|
headers: { |
|
'Authorization': `Bearer ${apiKey}`, |
|
'Content-Type': 'application/json', |
|
}, |
|
}); |
|
|
|
|
|
if (!response.ok) { |
|
|
|
const errorData = await response.json().catch(() => ({})); |
|
throw new Error(`HTTP error! Status: ${response.status}, Message: ${errorData.message || response.statusText}`); |
|
} |
|
|
|
|
|
const data = await response.json(); |
|
|
|
|
|
|
|
if (data && Array.isArray(data.data)) { |
|
const allModelNames = data.data.map(model => model.id); |
|
|
|
|
|
const filteredModelNames = allModelNames.filter(modelName => |
|
!modelName.toLowerCase().includes('embedding') |
|
); |
|
|
|
return filteredModelNames; |
|
} else { |
|
|
|
throw new Error('Unexpected response format from the API. Could not find model list.'); |
|
} |
|
|
|
} catch (error) { |
|
console.error('Error fetching model list:', error.message); |
|
|
|
throw error; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const StructuredAssessmentOutput = zod.object({ |
|
final_verdict: zod.string(), |
|
summary: zod.string(), |
|
insights: zod.array(zod.string()), |
|
}); |
|
|
|
export async function assessSolution(providerUrl, modelName, apiKey, solution, assessment_rules, portfolio_info) { |
|
const template = await retrieveTemplate("assess"); |
|
|
|
const assessment_template = formatTemplate(template, { |
|
notation_criterias: assessment_rules, |
|
business: portfolio_info, |
|
problem_description: solution.problem_description, |
|
solution_description: solution.solution_description, |
|
}); |
|
|
|
const assessment_full = await generateCompletion(providerUrl, modelName, apiKey, [ |
|
{ role: "user", content: assessment_template } |
|
]); |
|
|
|
const structured_template = await retrieveTemplate("extract"); |
|
const structured_filled_template = formatTemplate(structured_template, { |
|
"report": assessment_full, |
|
"response_schema": zod.toJSONSchema(StructuredAssessmentOutput) |
|
}) |
|
|
|
const extracted_info = await generateStructuredCompletion(providerUrl, modelName, apiKey, [{ role: "user", content: structured_filled_template }], StructuredAssessmentOutput); |
|
|
|
return { assessment_full, extracted_info }; |
|
} |
|
|
|
export async function refineSolution(providerUrl, modelName, apiKey, solution, insights, user_insights, assessment_rules, portfolio_info) { |
|
const template = await retrieveTemplate("refine"); |
|
|
|
const refine_template = formatTemplate(template, { |
|
"problem_description": solution.problem_description, |
|
"solution_description": solution.solution_description, |
|
"insights": insights.join("\n -"), |
|
"user_insights": user_insights, |
|
"business_info": portfolio_info, |
|
}); |
|
|
|
console.log(refine_template); |
|
|
|
const refined_idea = await generateCompletion(providerUrl, modelName, apiKey, [{ role: "user", content: refine_template }]); |
|
|
|
const newSolution = structuredClone(solution); |
|
newSolution.solution_description = refined_idea; |
|
|
|
return newSolution; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const FTOAnalysisTopicsSchema = zod.object({ |
|
topics: zod.array(zod.string()) |
|
}); |
|
|
|
|
|
|
|
|
|
async function getFtoAnalysisTopics(providerUrl, modelName, apiKey, idea, count) { |
|
const template = await retrieveTemplate("fto_topics"); |
|
|
|
const structured_template = formatTemplate(template, { |
|
"problem_description": idea.problem_description, |
|
"solution_description": idea.solution_description, |
|
"response_schema": zod.toJSONSchema(FTOAnalysisTopicsSchema), |
|
"max_topic_count": count |
|
}); |
|
|
|
const topics = await generateStructuredCompletion(providerUrl, modelName, apiKey, [{ role: "user", content: structured_template }], FTOAnalysisTopicsSchema); |
|
|
|
return topics; |
|
} |
|
|
|
|
|
|
|
|
|
async function assessFTOReport(providerUrl, modelName, apiKey, solution, fto_report, portfolio_info) { |
|
const template = await retrieveTemplate("fto_assess"); |
|
|
|
const assessment_template = formatTemplate(template, { |
|
business: portfolio_info, |
|
fto_report: fto_report, |
|
problem_description: solution.problem_description, |
|
solution_description: solution.solution_description, |
|
}); |
|
|
|
console.log("FTO Length: " + assessment_template.length); |
|
|
|
const assessment_full = await generateCompletion(providerUrl, modelName, apiKey, [ |
|
{ role: "user", content: assessment_template } |
|
]); |
|
|
|
const structured_template = await retrieveTemplate("extract"); |
|
const structured_filled_template = formatTemplate(structured_template, { |
|
"report": assessment_full, |
|
"response_schema": zod.toJSONSchema(StructuredAssessmentOutput) |
|
}) |
|
|
|
const extracted_info = await generateStructuredCompletion(providerUrl, modelName, apiKey, [{ role: "user", content: structured_filled_template }], StructuredAssessmentOutput); |
|
|
|
return { assessment_full, extracted_info }; |
|
} |
|
|
|
export async function runFTOAnalysis(providerUrl, providerModel, apiKey, solution, portfolio_info, ftoTopicCount) { |
|
const fto_topics = await getFtoAnalysisTopics(providerUrl, providerModel, apiKey, solution, ftoTopicCount); |
|
console.log(fto_topics); |
|
|
|
const fto_report = await performDeepSearch(fto_topics.topics); |
|
|
|
console.log(fto_report); |
|
|
|
const assess_results = await assessFTOReport(providerUrl, providerModel, apiKey, solution, fto_report, portfolio_info); |
|
console.log(assess_results.extracted_info); |
|
|
|
return { |
|
fto_topics: fto_topics, |
|
fto_report: fto_report, |
|
assessment_full: assess_results.assessment_full, |
|
extracted_info: assess_results.extracted_info, |
|
}; |
|
|
|
} |
|
|