Official Thesaurus plugin

Settings

name

Thesaurus

description

Get 10 context-aware word alternatives from OpenAI

icon

menu_book

setting

API Key

setting

OpenAI model (default is gpt-3.5-turbo)

instructions

Notice: This plugin is deprecated by its author. Its functionality now exists within the generic AmpleAI plugin.



Setting up Thesaurus

0. Install the plugin
1. Open the plugin settings and paste the OpenAI key you have generated

Using this plugin
Installing this plugin allows a user to quickly generate 10 replacement word or phrases that are contextually appropriate.





"I don't always generate alternate words, but when I do, I prefer Thesaurus"


 
{
// --------------------------------------------------------------------------------------
constants: {
defaultSystemPrompt: "You are a helpful assistant.",
model: app => (app.settings["OpenAI model (default is gpt-3.5-turbo)"]?.trim() || "gpt-3.5-turbo"),
pluginName: "Thesaurus",
},
 
// --------------------------------------------------------------------------------------
replaceText: async function (app, text) {
if (this._stopForApiKey(app)) return;
const noteUUID = app.context.noteUUID;
const note = await app.notes.find(noteUUID);
const noteContent = await note.content();
const messages = [
`You are a helpful thesaurus. Respond only with a numbered list of the 10 best suggestions to replace the word "${ text }"`,
`The suggested replacements will be inserted in place of the ${ text } token in the following markdown document:\n~~~\n${ noteContent.replace(text, `${ text }`) }\n~~~`,
`Respond with up to 10 word alternatives that can be inserted into the document, each of which is 3 or less words. Do not repeat the input content. Do not explain how you derived your answer. Do not explain why you chose your answer. Do not respond with the token itself.`
];
console.log("Awaiting", messages)
return await this._composeQuery(app, text, messages);
},
 
// --------------------------------------------------------------------------------------
async _composeQuery(app, text, messages) {
console.log("Requesting completion for", text);
const optionString = await this._callOpenAICompletion(app, "thesaurus", messages);
const optionList = optionString?.split("\n")?.map(word => word.replace(/^[\d]+\.?[\s]?/g, ""))
console.log("Received optionList", optionList)
if (optionList?.length) {
const promptOptions = optionList.map(option => ({ label: option.toLowerCase(), value: option.toLowerCase() }));
promptOptions.push({ label: "Generate more choices", value: "more" });
const selectedValue = await app.prompt(`Choose a replacement for "${ text }"`, {
inputs: [ { type: "radio", label: `${ optionList.length } synonym${ optionList.length === 1 ? "" : "s" } found`, options: promptOptions } ]
});
if (selectedValue === "more") {
const newMessages = messages.concat(`Do not include any of the following suggestions: ${ optionList.map(o => o.toLowerCase()).join(", ") }`)
return this._composeQuery(app, text, newMessages);
} else if (selectedValue) {
return selectedValue;
}
} else {
app.alert("No synonyms found");
}
return null;
},
 
// --------------------------------------------------------------------------------------
async _callOpenAICompletion(app, promptType, promptContent) {
let messages = [];
messages.push({ role: "system", content: this.constants.defaultSystemPrompt });
promptContent.forEach(content => {
messages.push({ role: "user", content: this._truncate(content) });
});
try {
const model = this.constants.model(app);
console.debug("Submitting messages", messages, "with model", model);
 
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${ app.settings["API Key"] }`,
"Content-Type": "application/json"
},
body: JSON.stringify({ model, messages, })
});
const result = await response.json();
const { choices: [ { message: { content } } ] } = result;
return content;
} catch (error) {
app.alert("Failed to call OpenAI: " + error);
return null;
}
},
 
// --------------------------------------------------------------------------------------
// GPT-3.5 has a 4097 token limit, so very much approximating that limit with this number
_truncate(text, limit = 15000) {
return text.length > limit ? text.slice(0, limit) : text;
},
 
// --------------------------------------------------------------------------------------
_stopForApiKey(app) {
if (app.settings["API Key"].trim()) {
return false;
} else {
app.alert("Please set your OpenAI API Key in the plugin settings");
return true;
}
}
}


linkChangelog

June 20. v1.01 Improve label in context bar from "Thesaurus: thesaurus" to just "Thesaurus"

April 24. v1.0 Initial implementation