ittuann_obsidian-gpt-litein.../main.js
2023-04-23 10:27:27 +08:00

439 lines
18 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// main.ts
var main_exports = {};
__export(main_exports, {
default: () => LightweightChatGPTPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian = require("obsidian");
var DEFAULT_SETTINGS = {
apiKey: "",
chatGPTModel: "gpt-3.5-turbo",
apiUrl: "https://api.openai.com",
apiUrlPath: "/v1/chat/completions",
temperature: 1,
maxTokens: 16,
defaultPrompt: "",
insertionMode: "end",
showSidebarIcon: true
};
var LightweightChatGPTPlugin = class extends import_obsidian.Plugin {
async onload() {
try {
await this.loadSettings();
} catch (error) {
console.error("Error loading settings:", error);
}
this.app.workspace.onLayoutReady(() => {
if (this.settings.showSidebarIcon) {
this.addSidebarIcon();
}
});
this.addCommand({
id: "open-lightweight-window",
name: "Open Lightweight Window",
callback: () => {
try {
new LightweightChatGPTWindow(this.app, this).open();
} catch (error) {
console.error("Error opening Lightweight ChatGPT Plugin Window:", error);
}
}
// hotkeys: [
// {
// modifiers: ['CTRL'],
// key: 'k',
// },
// ]
});
try {
this.addSettingTab(new LightweightChatGPTSettingTab(this.app, this));
} catch (error) {
console.error("Error adding settings tab:", error);
}
}
addSidebarIcon() {
try {
this.ribbonIconEl = this.addRibbonIcon("feather", "GPT-LiteInquirer", (evt) => {
try {
new LightweightChatGPTWindow(this.app, this).open();
} catch (error) {
console.error("Error opening Lightweight ChatGPT Plugin Window:", error);
}
});
} catch (error) {
console.error("Error adding sidebar icon:", error);
}
}
removeSidebarIcon() {
if (this.ribbonIconEl) {
try {
this.ribbonIconEl.remove();
} catch (error) {
console.error("Error closing sidebar icon:", error);
}
}
}
onunload() {
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
};
var LightweightChatGPTWindow = class extends import_obsidian.Modal {
constructor(app, plugin) {
super(app);
this.isSendingRequest = false;
this.plugin = plugin;
}
onOpen() {
const { contentEl } = this;
contentEl.createEl("h2", { text: "GPT Lite Inquirer Window" });
const activeView = this.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView);
const selectedText = activeView ? activeView.editor.getSelection() : "";
this.inputTextArea = contentEl.createEl("textarea");
this.inputTextArea.classList.add("gpt-input-textarea");
this.inputTextArea.rows = 4;
this.inputTextArea.placeholder = "Enter your text here ...";
if (!this.plugin.settings.defaultPrompt && selectedText) {
this.inputTextArea.value = `${selectedText}
----
`;
} else if (this.plugin.settings.defaultPrompt && !selectedText) {
this.inputTextArea.value = `${this.plugin.settings.defaultPrompt}
`;
} else if (this.plugin.settings.defaultPrompt && selectedText) {
this.inputTextArea.value = `${selectedText}
----
${this.plugin.settings.defaultPrompt}
`;
} else {
this.inputTextArea.value = "";
}
this.inputTextArea.addEventListener("keydown", (event) => {
if (event.key === "Enter" && !event.shiftKey && !event.ctrlKey) {
event.preventDefault();
this.insertAtCursor(this.inputTextArea, "\n");
} else if (event.key === "Enter" && event.ctrlKey) {
event.preventDefault();
sendButton.click();
}
});
contentEl.createEl("hr");
const maxTokensContainer = contentEl.createEl("div");
maxTokensContainer.className = "max-tokens-container";
const maxTokensLabelContainer = maxTokensContainer.createEl("div");
maxTokensLabelContainer.createEl("label", { text: "Max tokens:" });
const maxTokensDescription = maxTokensLabelContainer.createEl("p", { text: "Max OpenAI ChatGpt Tokens" });
maxTokensDescription.classList.add("max-tokens-description");
this.maxTokensInput = maxTokensContainer.createEl("input", { type: "number" });
this.maxTokensInput.placeholder = "Enter max Tokens number";
this.maxTokensInput.classList.add("max-tokens-input");
this.maxTokensInput.min = "1";
this.maxTokensInput.max = "2048";
this.maxTokensInput.value = this.plugin.settings.maxTokens.toString();
this.maxTokensInput.addEventListener("input", () => {
if (parseInt(this.maxTokensInput.value) > parseInt(this.maxTokensInput.max)) {
this.maxTokensInput.value = this.maxTokensInput.max;
new import_obsidian.Notice(`Max tokens cannot exceed ${this.maxTokensInput.max}`);
} else if (!parseInt(this.maxTokensInput.value) && parseInt(this.maxTokensInput.value) < parseInt(this.maxTokensInput.min)) {
this.maxTokensInput.value = this.maxTokensInput.min;
new import_obsidian.Notice(`Max tokens cannot be less than ${this.maxTokensInput.min}`);
}
});
const buttonSendContainer = contentEl.createEl("div");
buttonSendContainer.style.marginTop = "1rem";
const sendButton = buttonSendContainer.createEl("button", {
text: "Send"
}, (el) => {
el.style.backgroundColor = "green";
el.style.color = "white";
});
const responseDividerLine = contentEl.createEl("hr");
responseDividerLine.style.display = "none";
this.outputContainer = contentEl.createEl("div");
this.outputContainer.classList.add("output-container");
const buttonsContainer = contentEl.createEl("div");
buttonsContainer.style.display = "flex";
buttonsContainer.style.marginTop = "1rem";
const copyToClipboardButton = buttonsContainer.createEl("button", {
text: "Copy to clipboard"
}, (el) => {
el.style.backgroundColor = "green";
el.style.color = "white";
});
copyToClipboardButton.style.marginRight = "1rem";
copyToClipboardButton.style.display = "none";
const addToPostButton = buttonsContainer.createEl("button", { text: "Add to current document" });
addToPostButton.style.marginRight = "1rem";
addToPostButton.style.display = "none";
sendButton.addEventListener("click", async () => {
if (!parseInt(this.maxTokensInput.value)) {
new import_obsidian.Notice(`Use the default value of ${this.plugin.settings.maxTokens.toString()} for max Tokens`);
this.maxTokensInput.value = this.plugin.settings.maxTokens.toString();
}
if (!this.plugin.settings.apiKey) {
new import_obsidian.Notice("Please enter your API key in the plugin settings.");
return;
}
if (!this.inputTextArea.value) {
new import_obsidian.Notice("Please Enter text");
return;
}
if (this.isSendingRequest) {
return;
}
this.isSendingRequest = true;
sendButton.textContent = "Sending ...";
sendButton.textContent = "Waiting for API full response ...";
try {
new import_obsidian.Notice("Sending...");
this.responseAPIText = await this.sendRequestToChatGPT();
if (!this.responseAPIText) {
this.outputContainer.empty();
responseDividerLine.style.display = "none";
copyToClipboardButton.style.display = "none";
addToPostButton.style.display = "none";
}
this.outputContainer.createEl("p", { text: this.responseAPIText });
sendButton.textContent = "Send";
responseDividerLine.style.display = "block";
copyToClipboardButton.style.display = "block";
addToPostButton.style.display = "block";
} catch (error) {
sendButton.textContent = "Send";
console.error("Error during API request:", error);
} finally {
this.isSendingRequest = false;
}
});
copyToClipboardButton.addEventListener("click", () => {
this.copyToClipboard(this.responseAPIText);
});
addToPostButton.addEventListener("click", () => {
this.appendToCurrentNote(this.inputTextArea.value, this.responseAPIText, this.plugin.settings.insertionMode);
});
}
async sendRequestToChatGPT() {
const maxTokens = parseInt(this.maxTokensInput.value);
try {
const response = await (0, import_obsidian.request)({
url: this.plugin.settings.apiUrl + this.plugin.settings.apiUrlPath,
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${this.plugin.settings.apiKey}`
},
body: JSON.stringify({
model: this.plugin.settings.chatGPTModel,
max_tokens: maxTokens,
temperature: this.plugin.settings.temperature,
stream: false,
messages: [
{ role: "user", content: this.inputTextArea.value }
]
})
});
const currentResult = JSON.parse(response);
if (currentResult.choices && currentResult.choices.length > 0) {
const gptResponse = currentResult.choices[0].message.content;
return gptResponse;
} else if (currentResult.error) {
throw new Error(JSON.stringify(currentResult.error));
} else {
throw new Error("Unexpected API response format");
}
} catch (error) {
console.error("Error during API request:", error);
new import_obsidian.Notice(
"Error during API request: " + error.message
);
}
}
insertAtCursor(textArea, text) {
const startPos = textArea.selectionStart;
const endPos = textArea.selectionEnd;
textArea.value = textArea.value.substring(0, startPos) + text + textArea.value.substring(endPos, textArea.value.length);
textArea.selectionStart = startPos + text.length;
textArea.selectionEnd = startPos + text.length;
}
async appendToCurrentNote(sentText, receivedText, insertionMode) {
const receivedAPIText = receivedText || "";
if (receivedAPIText.length <= 0) {
new import_obsidian.Notice("No text to add");
return;
}
const activeView = this.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView);
const activeLeaf = activeView == null ? void 0 : activeView.leaf;
if (activeView && activeLeaf && activeLeaf.view instanceof import_obsidian.MarkdownView) {
const editor = activeLeaf.view.editor;
const formattedText = `
---
${receivedAPIText}
---
`;
if (insertionMode === "end") {
const lastLine = editor.lastLine();
editor.replaceRange(formattedText, { line: lastLine + 1, ch: 0 });
} else if (insertionMode === "current") {
const cursorPosition = editor.getCursor();
const currentLine = cursorPosition.line;
editor.replaceRange(formattedText, { line: currentLine + 1, ch: 0 });
}
} else {
new import_obsidian.Notice("Cannot append content to the current view. Please open a markdown note.");
}
}
async copyToClipboard(receivedText) {
const receivedAPIText = receivedText || "";
if (receivedAPIText.length > 0) {
navigator.clipboard.writeText(receivedAPIText).then(() => {
new import_obsidian.Notice("Copied to clipboard!");
}).catch((error) => {
console.error("Error copying to clipboard:", error);
new import_obsidian.Notice("Error copying to clipboard");
});
} else {
new import_obsidian.Notice("No text to copy");
}
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
var LightweightChatGPTSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: "Settings Lightweight ChatGPT Window" });
new import_obsidian.Setting(containerEl).setName("API Key*").setDesc(
createFragment((frag) => {
frag.appendText("Enter your OpenAI API key. ");
frag.appendText("If you don't have it, you can ");
frag.createEl("a", {
href: "https://platform.openai.com/account/api-keys",
text: "Click Here"
});
frag.appendText(" to apply.");
})
).addText((text) => text.setPlaceholder("Enter your API key").setValue(this.plugin.settings.apiKey).onChange(async (value) => {
this.plugin.settings.apiKey = value;
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("OpenAI Model").setDesc("Select the OpenAI model to use.").addDropdown((dropDown) => dropDown.addOption("gpt-3.5-turbo", "gpt-3.5-turbo").setValue(this.plugin.settings.chatGPTModel).onChange(async (value) => {
this.plugin.settings.chatGPTModel = value;
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("API URL*").setDesc("Modify here if you want to use a self-built server, otherwise keep the default without any changes.").addText((text) => text.setPlaceholder("https://api.openai.com").setValue(this.plugin.settings.apiUrl).onChange(async (value) => {
this.plugin.settings.apiUrl = value;
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("API URL Path*").setDesc("Modify here if you want to use a self-built server, otherwise keep the default without any changes.").addText((text) => text.setPlaceholder("/v1/chat/completions").setValue(this.plugin.settings.apiUrlPath).onChange(async (value) => {
this.plugin.settings.apiUrlPath = value;
await this.plugin.saveSettings();
}));
containerEl.createEl("h6", { text: "ChatGPT Model setting" });
new import_obsidian.Setting(containerEl).setName("Temperature").setDesc("Enter the temperature value between 0 and 2 (inclusive) for the API response").addText((text) => text.setPlaceholder("Enter temperature").setValue(this.plugin.settings.temperature.toString()).onChange(async (value) => {
let parsedValue = parseFloat(value);
if (parsedValue < 0) {
parsedValue = 0;
} else if (parsedValue > 2) {
parsedValue = 2;
}
this.plugin.settings.temperature = parsedValue;
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("Default Max Tokens").setDesc(this.plugin.settings.chatGPTModel === "gpt-4" ? "Enter the maximum number of tokens for the API response (integer, min: 1, max: 4096)" : "Enter the maximum number of tokens for the API response (integer, min: 1, max: 2048)").addText((text) => text.setPlaceholder("Enter max tokens").setValue(this.plugin.settings.maxTokens.toString()).onChange(async (value) => {
let parsedValue = parseInt(value);
let parsedMaxValue = 2048;
if (this.plugin.settings.chatGPTModel === "gpt-4") {
parsedMaxValue = 4096;
}
if (parsedValue < 1) {
parsedValue = 1;
} else if (parsedValue > parsedMaxValue) {
parsedValue = parsedMaxValue;
}
this.plugin.settings.maxTokens = parsedValue;
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("Default Prompt").setDesc(
"Default Prompt will be automatically inserted into the requested Prompt. (Not necessary)"
).addTextArea((text) => text.setPlaceholder("Enter Default Prompt").setValue(this.plugin.settings.defaultPrompt).onChange(async (value) => {
this.plugin.settings.defaultPrompt = value;
await this.plugin.saveSettings();
}));
containerEl.createEl("h6", { text: "Additional setting" });
new import_obsidian.Setting(containerEl).setName("Insertion Mode").setDesc("Choose how to insert text").addDropdown((dropdown) => dropdown.addOption("end", "Insert at end of document").addOption("current", "Insert at current position").setValue(this.plugin.settings.insertionMode).onChange(async (value) => {
this.plugin.settings.insertionMode = value;
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("Show Sidebar Icon").setDesc("Toggle to show or hide the sidebar icon").addToggle((toggle) => toggle.setValue(this.plugin.settings.showSidebarIcon).onChange(async (value) => {
this.plugin.settings.showSidebarIcon = value;
await this.plugin.saveSettings();
if (value) {
this.plugin.addSidebarIcon();
} else {
this.plugin.removeSidebarIcon();
}
}));
const politeMessage = containerEl.createEl("p", {
cls: "settings-polite-message"
});
politeMessage.textContent = "If you enjoy this plugin or would like to show your support, please consider giving it a free star on GitHub~ Your appreciation means a lot to me!";
const githubLink = containerEl.createEl("div", {
cls: "settings-github-link-container"
});
const githubAnchor = githubLink.createEl("a", {
cls: "settings-github-link"
});
const githubLogo = githubAnchor.createEl("img", {
cls: "settings-github-logo"
});
githubAnchor.href = "https://github.com/ittuann/obsidian-gpt-liteinquirer-plugin";
githubAnchor.target = "_blank";
githubAnchor.rel = "noopener";
const githubText = githubAnchor.createEl("span", {
text: "View on GitHub"
});
githubLogo.src = "https://assets.stickpng.com/images/5847f98fcef1014c0b5e48c0.png";
githubLogo.alt = "GitHub";
githubLogo.style.width = "24px";
githubLogo.style.height = "24px";
githubLogo.style.verticalAlign = "middle";
githubText.style.display = "inline-block";
githubText.style.verticalAlign = "middle";
}
};