) => {
setConfig(prev => ({ ...prev, ...updates }));
+ if (updates.enableCategoryDetection !== undefined) {
+ setEnableCategoryDetection(updates.enableCategoryDetection);
+ }
setDirty(true);
};
+ const resetVisionLLMPrompt = () => {
+ if (promptTextareaRef.current) {
+ promptTextareaRef.current.value = DefaultConfig.visionLLMPrompt;
+ }
+ updateConfig({ visionLLMPrompt: DefaultConfig.visionLLMPrompt });
+ };
+
+ const resetNotesLLMPrompt = () => {
+ if (notesPromptTextareaRef.current) {
+ notesPromptTextareaRef.current.value = DefaultConfig.notesLLMPrompt;
+ }
+ updateConfig({ notesLLMPrompt: DefaultConfig.notesLLMPrompt });
+ };
+
if (!initialized) {
return Loading...
;
}
@@ -96,6 +120,83 @@ const ConfigModalContent = ({
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{/*
diff --git a/src/components/modals/TestConfigModal.tsx b/src/components/modals/TestSetupModal.tsx
similarity index 95%
rename from src/components/modals/TestConfigModal.tsx
rename to src/components/modals/TestSetupModal.tsx
index 19cfae9..d0e2a5f 100644
--- a/src/components/modals/TestConfigModal.tsx
+++ b/src/components/modals/TestSetupModal.tsx
@@ -6,13 +6,13 @@ import { DateTime } from 'luxon';
import { DataManager } from '@/data/DataManager';
import { getModels } from '@/services/llm-service';
-interface TestConfigModalProps {
+interface TestSetupModalProps {
dataManager: DataManager;
plugin: VisionRecallPlugin;
onClose: () => void;
}
-const TestConfigView: React.FC = ({ dataManager, plugin, onClose }) => {
+const TestSetupView: React.FC = ({ dataManager, plugin, onClose }) => {
const settings = plugin.settings;
const [models, setModels] = useState([]);
@@ -127,7 +127,7 @@ const TestConfigView: React.FC = ({ dataManager, plugin, o
);
};
-export class TestConfigModal extends Modal {
+export class TestSetupModal extends Modal {
private metadata: any;
private plugin: VisionRecallPlugin;
@@ -139,11 +139,11 @@ export class TestConfigModal extends Modal {
onOpen() {
const { contentEl, titleEl } = this;
- titleEl.setText('Test config');
+ titleEl.setText('Test your setup');
const root = createRoot(contentEl);
root.render(
- this.close()}
diff --git a/src/services/llm-service.ts b/src/services/llm-service.ts
index d9e8d9c..f27ddf7 100644
--- a/src/services/llm-service.ts
+++ b/src/services/llm-service.ts
@@ -1,11 +1,30 @@
import { OPENROUTER_HEADERS } from '@/constants';
import { getLanguagePromptModifierIfIndicated } from '@/lib/languages';
import { tagsJsonSchema, TagsSchema } from '@/lib/tag-utils';
+import { Config } from '@/types/config-types';
import { VisionRecallPluginSettings } from '@/types/settings-types';
import { requestUrl, RequestUrlParam, RequestUrlResponse } from 'obsidian';
export const VISION_LLM_PROMPT = "Analyze this screenshot and describe its content and identify the type of screenshot if possible.";
+export const NOTES_LLM_PROMPT = "The following OCR text and vision analysis are from a screenshot. Summarize and synthesize the text and vision analysis and identify key information.";
+
+export const getVisionLLMPrompt = (config: Config) => {
+ if (config.visionLLMPrompt && config.visionLLMPrompt.trim() !== '') {
+ return config.visionLLMPrompt;
+ }
+
+ return VISION_LLM_PROMPT;
+}
+
+export const getNotesLLMPrompt = (config: Config) => {
+ if (config.notesLLMPrompt && config.notesLLMPrompt.trim() !== '') {
+ return config.notesLLMPrompt;
+ }
+
+ return NOTES_LLM_PROMPT;
+}
+
export function adjustEndpoint(apiEndpointUrl: string, shouldRemove: boolean): string {
const suffix = '/v1'
diff --git a/src/services/screenshot-processor.ts b/src/services/screenshot-processor.ts
index 0be8f5a..926d3af 100644
--- a/src/services/screenshot-processor.ts
+++ b/src/services/screenshot-processor.ts
@@ -1,7 +1,7 @@
import { App, FileManager, Notice, TFile, TFolder, arrayBufferToBase64, normalizePath } from 'obsidian';
import Tesseract, { createWorker, Worker } from 'tesseract.js';
import { VisionRecallPluginSettings } from '@/types/settings-types';
-import { DEFAULT_TAGS_AND_TITLE, TagsAndTitle, VISION_LLM_PROMPT, callLLMAPI } from '@/services/llm-service';
+import { DEFAULT_TAGS_AND_TITLE, TagsAndTitle, VISION_LLM_PROMPT, callLLMAPI, getNotesLLMPrompt, getVisionLLMPrompt } from '@/services/llm-service';
import VisionRecallPlugin from '@/main';
import { checkOCRText } from '@/lib/ocr-validation';
import { formatTags, sanitizeObsidianTag, tagsToCommaString } from '@/lib/tag-utils';
@@ -171,7 +171,7 @@ export class ScreenshotProcessor {
if (!ocrText || this.progressManager.isStoppedByUser()) return null;
ocrText = cleanOCRResultLanguageSpecific(ocrText, currentLanguageSetting || 'eng') || '';
- console.log('ocrText (after cleaning)', ocrText);
+ this.plugin.logger.debug('ocrText (after cleaning)', ocrText);
if (!ocrText) return null;
let validOCRText = await checkOCRText(ocrText, currentLanguageSetting || 'eng');
@@ -363,7 +363,7 @@ export class ScreenshotProcessor {
languagePromptModifier = getLanguagePromptModifierIfIndicated(this.settings, true);
}
- let textPayload = VISION_LLM_PROMPT + languagePromptModifier;
+ let textPayload = getVisionLLMPrompt(this.plugin.dataManager.getConfig()) + languagePromptModifier;
this.plugin.logger.debug('Vision LLM prompt:', textPayload);
const visionPayload = {
@@ -399,19 +399,23 @@ export class ScreenshotProcessor {
private async generateNotes(ocrText: string, visionLLMResponse: string, settings: VisionRecallPluginSettings): Promise {
try {
-
+ const config = this.plugin.dataManager.getConfig();
const languagePromptModifier = getLanguagePromptModifierIfIndicated(settings, true);
- let endpointPrompt = `The following text is from a screenshot. Summarize the text and identify key information.`;
+ let endpointPrompt = getNotesLLMPrompt(config);
- const visionLLMCategories = Object.keys(visionLLMResponseCategoriesMap);
+ if (config.enableCategoryDetection) {
+ const visionLLMCategories = Object.keys(visionLLMResponseCategoriesMap);
- const visionLLMCategory = visionLLMCategories.find(category => visionLLMResponse.toLowerCase().includes(category));
+ const visionLLMCategory = visionLLMCategories.find(category => visionLLMResponse.toLowerCase().includes(category));
- if (visionLLMCategory) {
- endpointPrompt = visionLLMResponseCategoriesMap[visionLLMCategory];
+ if (visionLLMCategory) {
+ endpointPrompt = visionLLMResponseCategoriesMap[visionLLMCategory];
+ }
}
+ this.plugin.logger.debug('Generate Notes LLM prompt (without added language modifier, OCR text, or vision analysis that are added later):', endpointPrompt);
+
endpointPrompt += `${languagePromptModifier}\n\nOCR text:\n${ocrText}\n\nVision analysis:\n${visionLLMResponse}`
const endpointPayload = {
@@ -430,8 +434,8 @@ export class ScreenshotProcessor {
);
this.plugin.logger.debug('Generated notes:', generatedNotes ? generatedNotes.substring(0, 300) + '...' : 'API call failed or no notes generated');
- return generatedNotes;
+ return generatedNotes;
} catch (error) {
this.plugin.logger.error('Endpoint LLM API error:', error);
new Notice('Endpoint LLM API call failed. See console for details.');
@@ -502,6 +506,7 @@ export class ScreenshotProcessor {
let counter = 1;
while (this.app.vault.getAbstractFileByPath(notePath) && counter < 100) {
+ this.plugin.logger.debug(`Note title already exists: ${noteTitle}. Incrementing counter and trying again.`);
noteTitle = `${noteTitleBase} Notes (${counter}).md`;
notePath = normalizePath(`${outputNotesFolder}/${noteTitle}`);
counter++;
diff --git a/src/types/config-types.ts b/src/types/config-types.ts
index a91bf9b..01f3a1b 100644
--- a/src/types/config-types.ts
+++ b/src/types/config-types.ts
@@ -1,3 +1,5 @@
+import { VISION_LLM_PROMPT, NOTES_LLM_PROMPT } from '@/services/llm-service';
+
export interface Config {
enableAutoIntakeFolderProcessing?: boolean;
@@ -10,6 +12,12 @@ export interface Config {
experimentalFeatures?: string[];
+ visionLLMPrompt?: string;
+
+ enableCategoryDetection?: boolean; // this is rudimentarily implemented, so defaulting to false
+
+ notesLLMPrompt?: string;
+
[key: string]: unknown;
}
@@ -18,5 +26,8 @@ export const DefaultConfig: Config = {
enablePeriodicIntakeFolderProcessing: false,
intakeFolderPollingInterval: 300, // 300 seconds, or 5 minutes
defaultMinimizedProgressDisplay: false, // Currently not functional
- experimentalFeatures: []
+ experimentalFeatures: [],
+ visionLLMPrompt: VISION_LLM_PROMPT,
+ enableCategoryDetection: false,
+ notesLLMPrompt: NOTES_LLM_PROMPT,
};
\ No newline at end of file
diff --git a/versions.json b/versions.json
index 923d4b8..7fc4684 100644
--- a/versions.json
+++ b/versions.json
@@ -14,5 +14,6 @@
"1.0.12": "1.8.3",
"1.0.13": "1.8.3",
"1.0.14": "1.8.3",
- "1.1.0": "1.8.3"
+ "1.1.0": "1.8.3",
+ "1.2.0": "1.8.3"
}
\ No newline at end of file