158 lines
4.3 KiB
JavaScript
158 lines
4.3 KiB
JavaScript
|
let selectedMenuItemId = null
|
||
|
let selectedText = null
|
||
|
let settings = {
|
||
|
model: "text-davinci-003",
|
||
|
temperature: 0.7,
|
||
|
max_tokens: 256,
|
||
|
top_p: 1,
|
||
|
frequency_penalty: 0,
|
||
|
presence_penalty: 0,
|
||
|
api_key: "apikeyhere"
|
||
|
}
|
||
|
|
||
|
const createContextMenu = (title) => {
|
||
|
chrome.contextMenus.create({
|
||
|
id: title.toLowerCase().split(" ").join("-"),
|
||
|
title: title,
|
||
|
contexts: ["browser_action", "selection"]
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const generatePrompt = () => {
|
||
|
let prompt
|
||
|
switch (selectedMenuItemId) {
|
||
|
case "explain-selection":
|
||
|
prompt = "Explain: '" + selectedText + "'"
|
||
|
break
|
||
|
case "complete-selection":
|
||
|
prompt = selectedText
|
||
|
break
|
||
|
case "respond-to-selection":
|
||
|
prompt = "Respond to this message: '" + selectedText + "'"
|
||
|
break
|
||
|
case "summerize-selection":
|
||
|
prompt = "Summerize: '" + selectedText + "'"
|
||
|
break
|
||
|
case "translate-selection":
|
||
|
// TODO: Add language selection to the settings on the popup.js file.
|
||
|
prompt = "Translate into english: '" + selectedText + "'"
|
||
|
break
|
||
|
default:
|
||
|
prompt = selectedText
|
||
|
break
|
||
|
}
|
||
|
return prompt
|
||
|
}
|
||
|
|
||
|
const sendTabMessage = (message) => {
|
||
|
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
|
||
|
if (tabs[0]) {
|
||
|
chrome.tabs.sendMessage(tabs[0].id, message)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const generateRequestBody = (prompt) => {
|
||
|
return JSON.stringify({ ...Object.fromEntries(Object.entries(settings).filter(([key]) => key != "api_key")), ...{ prompt: prompt } })
|
||
|
}
|
||
|
|
||
|
const handleAPIResponse = (json) => {
|
||
|
let apiResult = json.choices[0].text
|
||
|
|
||
|
if (selectedMenuItemId == null) {
|
||
|
// send to popup.js
|
||
|
chrome.runtime.sendMessage({
|
||
|
type: 'prompt-response',
|
||
|
data: apiResult
|
||
|
})
|
||
|
} else {
|
||
|
// send to content.js
|
||
|
sendTabMessage({ apiResult: apiResult })
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const handleAPIError = (error) => {
|
||
|
sendTabMessage({ apiResult: "Error. Please retry." })
|
||
|
}
|
||
|
|
||
|
const executeAPICall = (prompt) => {
|
||
|
fetch("https://api.openai.com/v1/completions", {
|
||
|
method: "POST",
|
||
|
headers: {
|
||
|
"Content-Type": "application/json",
|
||
|
"Authorization": "Bearer " + settings.api_key
|
||
|
},
|
||
|
body: generateRequestBody(prompt)
|
||
|
})
|
||
|
.then(response => response.json())
|
||
|
.then(handleAPIResponse).catch(handleAPIError)
|
||
|
}
|
||
|
|
||
|
const setLoading = () => {
|
||
|
if (selectedMenuItemId) {
|
||
|
sendTabMessage({ apiResult: "loading" })
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const requestAPIResponse = () => {
|
||
|
if (!selectedText) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
setLoading()
|
||
|
executeAPICall(generatePrompt())
|
||
|
}
|
||
|
|
||
|
const handleContextMenuClick = (info, tab) => {
|
||
|
selectedMenuItemId = info.menuItemId
|
||
|
requestAPIResponse()
|
||
|
}
|
||
|
|
||
|
const handleSettingsLoad = (storageResult) => {
|
||
|
if (storageResult.settings) {
|
||
|
setSettings(storageResult.settings)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const setSettings = (newSettings) => {
|
||
|
settings = {
|
||
|
model: newSettings.model,
|
||
|
temperature: parseFloat(newSettings.temperature),
|
||
|
max_tokens: parseInt(newSettings.max_tokens),
|
||
|
top_p: parseFloat(newSettings.top_p),
|
||
|
frequency_penalty: parseFloat(newSettings.frequency_penalty),
|
||
|
presence_penalty: parseFloat(newSettings.presence_penalty),
|
||
|
api_key: newSettings.api_key
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const handleMessage = (message, sender, sendResponse) => {
|
||
|
// TODO: Use a message type
|
||
|
if (message.hasOwnProperty("selectedText")) {
|
||
|
selectedText = message.selectedText
|
||
|
if (!selectedText || selectedText === "") {
|
||
|
sendTabMessage({ removeTooltip: true })
|
||
|
}
|
||
|
} else if (message.hasOwnProperty("model")) {
|
||
|
setSettings(message)
|
||
|
} else if (message.hasOwnProperty("retry")) {
|
||
|
requestAPIResponse()
|
||
|
} else if (message.hasOwnProperty("prompt")) {
|
||
|
selectedText = message.prompt
|
||
|
selectedMenuItemId = null
|
||
|
requestAPIResponse()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
createContextMenu("Explain Selection")
|
||
|
createContextMenu("Complete Selection")
|
||
|
createContextMenu("Respond to Selection")
|
||
|
createContextMenu("Summerize Selection")
|
||
|
createContextMenu("Translate Selection")
|
||
|
|
||
|
chrome.contextMenus.onClicked.addListener(handleContextMenuClick)
|
||
|
|
||
|
chrome.storage.sync.get("settings", handleSettingsLoad)
|
||
|
|
||
|
chrome.runtime.onMessage.addListener(handleMessage)
|