mirror of
https://github.com/cosmicoptima/loom.git
synced 2026-07-22 07:40:25 +00:00
added cohere support
This commit is contained in:
parent
88d6709311
commit
61e19f9ed9
4 changed files with 107 additions and 21 deletions
117
main.ts
117
main.ts
|
|
@ -12,6 +12,7 @@ import {
|
|||
WorkspaceLeaf,
|
||||
setIcon,
|
||||
} from "obsidian";
|
||||
import * as cohere from "cohere-ai";
|
||||
import GPT3Tokenizer from "gpt3-tokenizer";
|
||||
import { Configuration, OpenAIApi } from "openai";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
|
@ -21,9 +22,14 @@ const untildify = require("untildify") as any;
|
|||
|
||||
const tokenizer = new GPT3Tokenizer({ type: "codex" });
|
||||
|
||||
interface LoomSettings {
|
||||
apiKey: string;
|
||||
const PROVIDERS = ["openai", "openai-chat", "cohere"];
|
||||
type Provider = typeof PROVIDERS[number];
|
||||
|
||||
interface LoomSettings {
|
||||
openaiApiKey: string;
|
||||
cohereApiKey: string;
|
||||
|
||||
provider: Provider;
|
||||
model: string;
|
||||
maxTokens: number;
|
||||
temperature: number;
|
||||
|
|
@ -37,8 +43,10 @@ interface LoomSettings {
|
|||
}
|
||||
|
||||
const DEFAULT_SETTINGS: LoomSettings = {
|
||||
apiKey: "",
|
||||
openaiApiKey: "",
|
||||
cohereApiKey: "",
|
||||
|
||||
provider: "openai",
|
||||
model: "code-davinci-002",
|
||||
maxTokens: 60,
|
||||
temperature: 1,
|
||||
|
|
@ -51,15 +59,6 @@ const DEFAULT_SETTINGS: LoomSettings = {
|
|||
showExport: false,
|
||||
};
|
||||
|
||||
const CHAT_MODELS = [
|
||||
"gpt-3.5-turbo",
|
||||
"gpt-3.5-turbo-0301",
|
||||
"gpt-4",
|
||||
"gpt-4-0314",
|
||||
"gpt-4-32k",
|
||||
"gpt-4-32k-0314",
|
||||
];
|
||||
|
||||
type Color = "red" | "orange" | "yellow" | "green" | "blue" | "purple" | null;
|
||||
|
||||
interface Node {
|
||||
|
|
@ -110,11 +109,15 @@ export default class LoomPlugin extends Plugin {
|
|||
|
||||
setOpenAI() {
|
||||
const configuration = new Configuration({
|
||||
apiKey: this.settings.apiKey,
|
||||
apiKey: this.settings.openaiApiKey,
|
||||
});
|
||||
this.openai = new OpenAIApi(configuration);
|
||||
}
|
||||
|
||||
setCohere() {
|
||||
cohere.init(this.settings.cohereApiKey);
|
||||
}
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
await this.loadState();
|
||||
|
|
@ -122,6 +125,7 @@ export default class LoomPlugin extends Plugin {
|
|||
this.addSettingTab(new LoomSettingTab(this.app, this));
|
||||
|
||||
this.setOpenAI();
|
||||
this.setCohere();
|
||||
|
||||
this.statusBarItem = this.addStatusBarItem();
|
||||
this.statusBarItem.setText("Completing...");
|
||||
|
|
@ -858,7 +862,7 @@ export default class LoomPlugin extends Plugin {
|
|||
// complete, or visually display an error and return if that fails
|
||||
let completions;
|
||||
try {
|
||||
if (CHAT_MODELS.contains(this.settings.model)) {
|
||||
if (this.settings.provider === "openai-chat") {
|
||||
completions = (await this.openai.createChatCompletion({
|
||||
model: this.settings.model,
|
||||
messages: [
|
||||
|
|
@ -869,7 +873,7 @@ export default class LoomPlugin extends Plugin {
|
|||
temperature: this.settings.temperature,
|
||||
top_p: this.settings.topP,
|
||||
})).data.choices.map((choice) => choice.message?.content);
|
||||
} else {
|
||||
} else if (this.settings.provider === "openai") {
|
||||
completions = (
|
||||
await this.openai.createCompletion({
|
||||
model: this.settings.model,
|
||||
|
|
@ -882,21 +886,46 @@ export default class LoomPlugin extends Plugin {
|
|||
).data.choices.map((choice) => choice.text);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.response.status === 401)
|
||||
if (e.response.status === 401 && ["openai", "openai-chat"].includes(this.settings.provider))
|
||||
new Notice(
|
||||
"OpenAI API key is invalid. Please provide a valid key in the settings."
|
||||
);
|
||||
else if (e.response.status === 429)
|
||||
else if (e.response.status === 429 && ["openai", "openai-chat"].includes(this.settings.provider))
|
||||
new Notice("OpenAI API rate limit exceeded.");
|
||||
else
|
||||
new Notice(
|
||||
"Unknown OpenAI API error: " + e.response.data.error.message
|
||||
"Unknown API error: " + e.response.data.error.message
|
||||
);
|
||||
|
||||
this.statusBarItem.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.settings.provider === "cohere") {
|
||||
const response = await cohere.generate({
|
||||
model: this.settings.model,
|
||||
prompt,
|
||||
max_tokens: this.settings.maxTokens,
|
||||
num_generations: this.settings.n,
|
||||
temperature: this.settings.temperature,
|
||||
p: this.settings.topP,
|
||||
});
|
||||
if (response.statusCode !== 200) {
|
||||
new Notice("Cohere API responded with status code " + response.statusCode);
|
||||
|
||||
this.statusBarItem.style.display = "none";
|
||||
return;
|
||||
}
|
||||
completions = response.body.generations.map((generation) => generation.text);
|
||||
}
|
||||
|
||||
if (completions === undefined) {
|
||||
new Notice("Invalid provider: " + this.settings.provider);
|
||||
|
||||
this.statusBarItem.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
// create a child node to the current node for each completion
|
||||
let ids = [];
|
||||
for (let completion of completions) {
|
||||
|
|
@ -1079,6 +1108,7 @@ export default class LoomPlugin extends Plugin {
|
|||
async save() {
|
||||
await this.saveData({ settings: this.settings, state: this.state });
|
||||
this.setOpenAI();
|
||||
this.setCohere();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1215,6 +1245,29 @@ class LoomView extends ItemView {
|
|||
);
|
||||
};
|
||||
|
||||
const providerDiv = settingsDiv.createDiv({ cls: "loom-setting" });
|
||||
providerDiv.createEl("label", { text: "Provider" });
|
||||
const providerSelect = providerDiv.createEl("select", {
|
||||
attr: { id: "loom-provider" },
|
||||
});
|
||||
const providerOptions = [
|
||||
{ name: "None", value: "none" },
|
||||
{ name: "OpenAI (Completion)", value: "openai" },
|
||||
{ name: "OpenAI (Chat)", value: "openai-chat" },
|
||||
{ name: "Cohere", value: "cohere" },
|
||||
];
|
||||
providerOptions.forEach((option) => {
|
||||
const optionEl = providerSelect.createEl("option", {
|
||||
text: option.name,
|
||||
attr: { value: option.value },
|
||||
});
|
||||
if (option.value === settings.provider) {
|
||||
optionEl.setAttribute("selected", "selected");
|
||||
}
|
||||
});
|
||||
providerSelect.addEventListener("change", () =>
|
||||
this.app.workspace.trigger("loom:set-setting", "provider", providerSelect.value)
|
||||
);
|
||||
setting(
|
||||
"Model",
|
||||
"loom-model",
|
||||
|
|
@ -1613,12 +1666,34 @@ class LoomSettingTab extends PluginSettingTab {
|
|||
method2.createEl("kbd", { text: "Loom: Open Loom pane" });
|
||||
method2.createEl("span", { text: " command." });
|
||||
|
||||
new Setting(containerEl).setName("Provider").addDropdown((dropdown) => {
|
||||
dropdown.addOption("openai", "OpenAI (Completion)");
|
||||
dropdown.addOption("openai-chat", "OpenAI (Chat)");
|
||||
dropdown.addOption("cohere", "Cohere");
|
||||
dropdown.setValue(this.plugin.settings.provider);
|
||||
dropdown.onChange(async (value) => {
|
||||
if (PROVIDERS.find((provider) => provider === value))
|
||||
this.plugin.settings.provider = value;
|
||||
await this.plugin.save();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("OpenAI API key")
|
||||
.setDesc("Required")
|
||||
.setDesc("Required if using OpenAI")
|
||||
.addText((text) =>
|
||||
text.setValue(this.plugin.settings.apiKey).onChange(async (value) => {
|
||||
this.plugin.settings.apiKey = value;
|
||||
text.setValue(this.plugin.settings.openaiApiKey).onChange(async (value) => {
|
||||
this.plugin.settings.openaiApiKey = value;
|
||||
await this.plugin.save();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Cohere API key")
|
||||
.setDesc("Required if using Cohere")
|
||||
.addText((text) =>
|
||||
text.setValue(this.plugin.settings.cohereApiKey).onChange(async (value) => {
|
||||
this.plugin.settings.cohereApiKey = value;
|
||||
await this.plugin.save();
|
||||
})
|
||||
);
|
||||
|
|
|
|||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -10,6 +10,7 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.191",
|
||||
"cohere-ai": "^6.1.0",
|
||||
"gpt3-tokenizer": "^1.1.5",
|
||||
"lodash": "^4.17.21",
|
||||
"openai": "^3.2.0",
|
||||
|
|
@ -564,6 +565,11 @@
|
|||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cohere-ai": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cohere-ai/-/cohere-ai-6.1.0.tgz",
|
||||
"integrity": "sha512-1hx13cEB0QqxkW213JhAOw8Q2jzCeo6GUFSQ5lsOQPNtDFhSZZusTD/+DcAvd8IVw2y/Cm+pfK3tofPngVG3BA=="
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.191",
|
||||
"cohere-ai": "^6.1.0",
|
||||
"gpt3-tokenizer": "^1.1.5",
|
||||
"lodash": "^4.17.21",
|
||||
"openai": "^3.2.0",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@
|
|||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
.loom-setting select {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
.loom-collapse {
|
||||
margin-left: 0.6em;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue