From 65c7116dcb7e78122b93a22633e16f5797715ba2 Mon Sep 17 00:00:00 2001 From: Justyn Shull Date: Sun, 7 Jul 2024 17:26:39 -0500 Subject: [PATCH 1/3] Fix #32 by always selecting a model if there's only a single one in the list. Also remove deprecated paramaters: summarizePrompt, tagPrompt, imagePrompt, temperature, maxTokens, defaultTextModel. Most of them weren't used anymore, and defaultTextModel doesn't make sense the way it was being used. --- src/init.ts | 45 +++++++++++---------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/src/init.ts b/src/init.ts index 93cbc9d..579a146 100644 --- a/src/init.ts +++ b/src/init.ts @@ -41,18 +41,11 @@ export type AISettings = { promptInstructions: PromptInstructions; // These are deprecated and will be removed in a future release - summarizePrompt: string; - tagPrompt: string; - imagePrompt: string; - temperature: number; - maxTokens: number; - defaultTextModel: string; openAIBaseUrl: string; dallEBaseUrl: string; requireAuth: boolean; secretName: string; provider: Provider; - backwardsCompat: boolean; // Above is left for backwards compatibility }; @@ -228,7 +221,6 @@ export async function configureSelectedImageModel(model: ImageModelConfig) { async function loadAndMergeSettings() { const defaultSettings = { - defaultTextModel: "gpt-3.5-turbo", openAIBaseUrl: "https://api.openai.com/v1", dallEBaseUrl: "https://api.openai.com/v1", requireAuth: true, @@ -250,11 +242,6 @@ async function loadAndMergeSettings() { tagRules: "", }; const newSettings = await readSetting("ai", {}); - if (newSettings.defaultTextModel) { - newSettings.backwardsCompat = true; - } else { - newSettings.backwardsCompat = false; - } const newCombinedSettings = { ...defaultSettings, ...newSettings }; newCombinedSettings.chat = { ...defaultChatSettings, @@ -272,27 +259,7 @@ export async function initializeOpenAI(configure = true) { const newCombinedSettings = await loadAndMergeSettings(); let errorMessage = ""; - if (!newCombinedSettings.textModels && newCombinedSettings.defaultTextModel) { - // Backwards compatibility - if there isn't a textModels object, use the old behavior of config - newCombinedSettings.textModels = [ - { - name: "default", - description: "Default model", - modelName: newCombinedSettings.defaultTextModel, - provider: newCombinedSettings.provider, - secretName: newCombinedSettings.secretName, - }, - ]; - await setSelectedTextModel(newCombinedSettings.textModels[0]); - } else if ( - newCombinedSettings.textModels.length > 0 && - newCombinedSettings.backwardsCompat - ) { - errorMessage = - "Both textModels and defaultTextModel found in ai settings. Please remove defaultTextModel."; - } else if ( - !newCombinedSettings.textModels && !newCombinedSettings.defaultTextModel - ) { + if (!newCombinedSettings.textModels) { errorMessage = "No textModels found in ai settings"; } @@ -310,6 +277,16 @@ export async function initializeOpenAI(configure = true) { console.log("aiSettings unchanged", aiSettings); } + if (aiSettings.textModels.length === 1) { + // If there's only one text model, set it as the selected model + await setSelectedTextModel(aiSettings.textModels[0]); + } + + if (aiSettings.imageModels.length === 1) { + // If there's only one image model, set it as the selected model + await setSelectedImageModel(aiSettings.imageModels[0]); + } + if (configure) { await getAndConfigureModel(); if (aiSettings.imageModels && aiSettings.imageModels.length > 0) { From 74afd58bd3391bc6cbe2aad008b90208409d62b5 Mon Sep 17 00:00:00 2001 From: Justyn Shull Date: Sun, 7 Jul 2024 17:35:51 -0500 Subject: [PATCH 2/3] Handle when imageModels is empty or undefined --- sbai.ts | 5 +++++ src/init.ts | 1 + 2 files changed, 6 insertions(+) diff --git a/sbai.ts b/sbai.ts index 3aeaa00..b04ad01 100644 --- a/sbai.ts +++ b/sbai.ts @@ -399,6 +399,11 @@ export async function streamChatOnPage() { export async function promptAndGenerateImage() { await initIfNeeded(); + if (!aiSettings.imageModels || aiSettings.imageModels.length === 0) { + await editor.flashNotification("No image models available.", "error"); + return; + } + try { const prompt = await editor.prompt("Enter a prompt for DALLĀ·E:"); if (!prompt || !prompt.trim()) { diff --git a/src/init.ts b/src/init.ts index 579a146..2fbd180 100644 --- a/src/init.ts +++ b/src/init.ts @@ -228,6 +228,7 @@ async function loadAndMergeSettings() { provider: "OpenAI", chat: {}, promptInstructions: {}, + imageModels: [], }; const defaultChatSettings: ChatSettings = { userInformation: "", From b3004a41e58b565e7775314c4d99d81c13a9959c Mon Sep 17 00:00:00 2001 From: Justyn Shull Date: Sun, 7 Jul 2024 17:40:45 -0500 Subject: [PATCH 3/3] Misc cleanup/formatting --- sbai.ts | 12 ++++++------ src/init.ts | 10 ++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/sbai.ts b/sbai.ts index b04ad01..efc4426 100644 --- a/sbai.ts +++ b/sbai.ts @@ -92,7 +92,7 @@ export async function selectImageModelFromConfig() { } /** - * Prompts the user for a custom prompt to send to the LLM. If the user has text selected, the selected text is used as the note content. + * Prompts the user for a custom prompt to send to the LLM. If the user has text selected, the selected text is used as the note content. * If the user has no text selected, the entire note is used as the note content. * The response is streamed to the cursor position. */ @@ -114,7 +114,7 @@ export async function callOpenAIwithNote() { { role: "system", content: - "You are an AI note assistant. Follow all user instructions and use the note context and note content to help follow those instructions. Use Markdown for any formatting.", + "You are an AI note assistant. Follow all user instructions and use the note context and note content to help follow those instructions. Use Markdown for any formatting.", }, { role: "user", @@ -156,7 +156,7 @@ export async function summarizeNote() { /** * Uses a built-in prompt to ask the LLM for a summary of either the entire note, or the selected - * text. Inserts the summary at the cursor's position. + * text. Inserts the summary at the cursor's position. */ export async function insertSummary() { const { summary, selectedTextInfo } = await summarizeNote(); @@ -170,7 +170,7 @@ export async function insertSummary() { /** * Uses a built-in prompt to ask the LLM for a summary of either the entire note, or the selected - * text. Opens the resulting summary in a temporary right pane. + * text. Opens the resulting summary in a temporary right pane. */ export async function openSummaryPanel() { const { summary } = await summarizeNote(); @@ -438,7 +438,7 @@ export async function promptAndGenerateImage() { await space.writeAttachment(prefix + finalFileName, decodedImage); // And then insert it with the prompt dall-e rewrote for us - // TODO: This uses the original prompt as alt-text, but sometimes it's kind of long. I'd like to let the user provide a template for how this looks. + // TODO: This uses the original prompt as alt-text, but sometimes it's kind of long. I'd like to let the user provide a template for how this looks. const markdownImg = `![${finalFileName}](${finalFileName})\n*${revisedPrompt}*`; await editor.insertAtCursor(markdownImg); @@ -465,7 +465,7 @@ export async function queryOpenAI( await initIfNeeded(); const messages: ChatMessage[] = []; const defaultSystemPrompt = - "You are an AI note assistant helping to render content for a note. Please follow user instructions and keep your response short and concise."; + "You are an AI note assistant helping to render content for a note. Please follow user instructions and keep your response short and concise."; messages.push({ role: "system", content: systemPrompt || defaultSystemPrompt, diff --git a/src/init.ts b/src/init.ts index 2fbd180..a61e10e 100644 --- a/src/init.ts +++ b/src/init.ts @@ -177,9 +177,7 @@ export async function configureSelectedModel(model: ModelConfig) { if (!model) { throw new Error("No model provided to configure"); } - if (model.requireAuth === undefined) { - model.requireAuth = aiSettings.requireAuth; - } + model.requireAuth = model.requireAuth ?? aiSettings.requireAuth; if (model.requireAuth) { const newApiKey = await readSecret(model.secretName || "OPENAI_API_KEY"); if (newApiKey !== apiKey) { @@ -264,7 +262,7 @@ export async function initializeOpenAI(configure = true) { errorMessage = "No textModels found in ai settings"; } - if (errorMessage !== "") { + if (errorMessage) { console.error(errorMessage); // await editor.flashNotification(errorMessage, "error"); throw new Error(errorMessage); @@ -290,7 +288,7 @@ export async function initializeOpenAI(configure = true) { if (configure) { await getAndConfigureModel(); - if (aiSettings.imageModels && aiSettings.imageModels.length > 0) { + if (aiSettings.imageModels.length > 0) { await getAndConfigureImageModel(); } } @@ -302,7 +300,7 @@ export async function initializeOpenAI(configure = true) { }; if (aiSettings.chat.userInformation) { chatSystemPrompt.content += - `\nThe user has provided the following information about their self: ${aiSettings.chat.userInformation}`; + `\nThe user has provided the following information about themselves: ${aiSettings.chat.userInformation}`; } if (aiSettings.chat.userInstructions) { chatSystemPrompt.content +=