Refactor settings and prompts for InlineAI integration

This commit is contained in:
FBarrca 2025-01-05 23:36:04 +01:00
parent e3a231813d
commit 7eb78cf88f
4 changed files with 118 additions and 31 deletions

View file

@ -2,8 +2,8 @@
import { ChatOpenAI } from "@langchain/openai";
import { ChatOllama } from "@langchain/ollama";
import { SystemMessage, HumanMessage, AIMessage } from "@langchain/core/messages";
import { MyPluginSettings } from "./settings";
import { App, MarkdownView } from "obsidian";
import { InlineAISettings } from "./settings";
import { App, MarkdownView, Notice } from "obsidian";
import { EditorView } from "@codemirror/view";
import { setGeneratedResponseEffect } from "./modules/AIExtension";
@ -18,7 +18,7 @@ export class ChatApiManager {
* Initializes the ChatApiManager with the given settings.
* @param settings - Configuration settings for the chat API.
*/
constructor(private settings: MyPluginSettings, app: App) {
constructor(private settings: InlineAISettings, app: App) {
this.app = app;
this.chatClient = this.initializeChatClient(settings);
}
@ -29,26 +29,32 @@ export class ChatApiManager {
* @returns An instance of ChatOpenAI or ChatOllama.
* @throws Error if the provider is unsupported or required settings are missing.
*/
private initializeChatClient(settings: MyPluginSettings): ChatOpenAI | ChatOllama {
switch (settings.provider) {
case "openai":
if (!settings.apiKey) {
throw new Error("OpenAI API key is required when using OpenAI as the provider.");
}
return new ChatOpenAI({
modelName: settings.model,
temperature: 0, // Set temperature to 0 for deterministic outputs
apiKey: settings.apiKey,
});
private initializeChatClient(settings: InlineAISettings): ChatOpenAI | ChatOllama {
try {
switch (settings.provider) {
case "openai":
if (!settings.apiKey) {
throw new Error("OpenAI API key is required when using OpenAI as the provider.");
}
return new ChatOpenAI({
modelName: settings.model,
temperature: 0, // Set temperature to 0 for deterministic outputs
apiKey: settings.apiKey,
});
case "ollama":
return new ChatOllama({
model: settings.model,
// Add other necessary configurations for Ollama if needed
});
case "ollama":
return new ChatOllama({
model: settings.model,
// Add other necessary configurations for Ollama if needed
});
default:
throw new Error(`Unsupported provider: ${settings.provider}`);
default:
throw new Error(`Unsupported provider: ${settings.provider}`);
}
} catch (error) {
console.error("Error initializing chat client:", error);
new Notice(`Failed to initialize chat client. ${error}`);
throw new Error("Failed to initialize chat client.");
}
}

35
src/default_prompts.ts Normal file
View file

@ -0,0 +1,35 @@
export const selectionPrompt = `
You are an advanced language model that performs text transformations based on specific instructions. Your task is to process input text to produce the desired output based on a given transformation type. You can handle tasks like adding emojis, making text longer or shorter, and converting text into tables, among many others. Use **Obsidian-flavored markdown** in all your transformations when applicable. Follow the examples provided to guide your responses.
It is **very important** that you follow the examples. Do not add anything at the start of the output like "Output:" or "Here's a rephrased version of the input text:" or anything similar. Just provide the transformed text.
**Examples:**
---
**Task:** Add Emojis.
**Prompt:** Add relevant emojis to make the text more engaging.
**Input:**
"Let's celebrate the success of our project."
**Output:**
"🎉 Let's celebrate the success of our project! 🚀👏"
---
**Task:** Convert to Table.
**Prompt:** Convert the text into an Obsidian table format.
**Input:**
"Name: John, Age: 30, Profession: Engineer"
**Output:**
| Name | Age | Profession |
|-------|-----|-------------|
| John | 30 | Engineer|
---
`
export const cursorPrompt = "Generate text based on cursor position.";

View file

@ -1,7 +1,7 @@
// main.ts
import { Plugin, MarkdownView, App } from "obsidian";
import { EditorView } from "@codemirror/view";
import { MyPluginSettings, DEFAULT_SETTINGS, MyPluginSettingTab } from "./settings";
import { InlineAISettings, DEFAULT_SETTINGS, MyPluginSettingTab } from "./settings";
import { commandEffect, FloatingTooltipExtension } from "./modules/WidgetExtension";
import { ChatApiManager } from "./api";
import { generatedResponseState } from "./modules/AIExtension";
@ -9,7 +9,7 @@ import { buildSelectionHiglightState, currentSelectionState, setSelectionInfoEff
import { diffExtension } from "./modules/diffExtension";
export default class MyPlugin extends Plugin {
settings: MyPluginSettings = DEFAULT_SETTINGS;
settings: InlineAISettings = DEFAULT_SETTINGS;
async onload() {
await this.loadSettings();

View file

@ -1,19 +1,24 @@
// MyPluginSettings.ts
import { App, PluginSettingTab, Setting } from "obsidian";
import MyPlugin from "./main";
import { cursorPrompt, selectionPrompt } from "./default_prompts";
// Interface for the settings
export interface MyPluginSettings {
export interface InlineAISettings {
provider: "openai" | "ollama";
model: string;
apiKey?: string;
selectionPrompt: string;
cursorPrompt: string;
}
// Default settings values
export const DEFAULT_SETTINGS: MyPluginSettings = {
provider: "openai",
model: "text-davinci-003",
export const DEFAULT_SETTINGS: InlineAISettings = {
provider: "ollama",
model: "llama3.2",
apiKey: "",
selectionPrompt: selectionPrompt,
cursorPrompt: cursorPrompt,
};
// Settings tab class to display settings in Obsidian UI
@ -29,13 +34,13 @@ export class MyPluginSettingTab extends PluginSettingTab {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", { text: "My Plugin Settings" });
// Provider setting
new Setting(containerEl)
.setName("Provider")
.setDesc("Choose between OpenAI or Ollama as your provider.")
.addDropdown(dropdown =>
.addDropdown(dropdown =>
dropdown
.addOption("openai", "OpenAI")
.addOption("ollama", "Ollama")
@ -51,7 +56,7 @@ export class MyPluginSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName("Model")
.setDesc("Specify the model to use.")
.addText(text =>
.addText(text =>
text
.setPlaceholder("e.g., text-davinci-003")
.setValue(this.plugin.settings.model)
@ -66,7 +71,7 @@ export class MyPluginSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName("OpenAI API Key")
.setDesc("Enter your OpenAI API key.")
.addText(text =>
.addText(text =>
text
.setPlaceholder("sk-...")
.setValue(this.plugin.settings.apiKey || "")
@ -76,5 +81,46 @@ export class MyPluginSettingTab extends PluginSettingTab {
})
);
}
// Advanced Section
containerEl.createEl("h3", { text: "Advanced Settings" });
// Selection Prompt setting
new Setting(containerEl)
.setName("Selection Prompt")
.setDesc("System Prompt used when the tooltip is triggered with selected text.")
.addTextArea((textarea) => {
textarea
.setPlaceholder("e.g., Summarize the selected text.")
.setValue(this.plugin.settings.selectionPrompt)
.onChange(async (value) => {
this.plugin.settings.selectionPrompt = value;
await this.plugin.saveSettings();
});
// Make the text area wider
textarea.inputEl.style.width = "25em";
textarea.inputEl.style.height = "10em";
});
// Cursor Prompt setting
new Setting(containerEl)
.setName("Cursor Prompt")
.setDesc("System Prompt used when the tooltip is triggered with selected text.")
.addTextArea((textarea) => {
textarea
.setPlaceholder("e.g., Generate text based on cursor position.")
.setValue(this.plugin.settings.cursorPrompt)
.onChange(async (value) => {
this.plugin.settings.cursorPrompt = value;
await this.plugin.saveSettings();
});
// Make the text area wider
textarea.inputEl.style.width = "25em";
textarea.inputEl.style.height = "10em";
});
}
}