AI_Assistant/background.js

158 lines
4.3 KiB
JavaScript
Raw Permalink Normal View History

2023-01-08 03:00:40 +00:00
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)