diff --git a/Changelog b/Changelog index 2e135a30..bf1d6b07 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,13 @@ -2024-03-?? Martin Dvorak - - * Released v2.1.0 - ... +2024-04-?? Martin Dvorak + + * Released v2.1.0 - Local LLMs support, Notes semantic search + and orphan library documents management. + * WIP: Feature: ollama integration brings privacy safe Wingman + via ollama hosted LLMs. + * WIP: Feature: embeddings calculation by ollama hosted LLM models + * WIP: Enhancement: improved LLM providers configuration: OpenAI and ollama + (environment vs. configuration; LLM model selection; provider choice) + * WIP: Enhancement: library orphans 2024-02-16 Martin Dvorak diff --git a/app/resources/qt/translations/mindforger_cs.qm b/app/resources/qt/translations/mindforger_cs.qm index 17762942..684203cd 100644 Binary files a/app/resources/qt/translations/mindforger_cs.qm and b/app/resources/qt/translations/mindforger_cs.qm differ diff --git a/app/resources/qt/translations/mindforger_cs.ts b/app/resources/qt/translations/mindforger_cs.ts index 54e741ce..29c6b818 100644 --- a/app/resources/qt/translations/mindforger_cs.ts +++ b/app/resources/qt/translations/mindforger_cs.ts @@ -308,52 +308,52 @@ Choose new library source: m8r::ConfigurationDialog::AppTab - + UI theme (<font color='#ff0000'>requires restart</font>) - + Menu (<font color='#ff0000'>requires restart</font>) - + Show the following view on application start - + Application font size - 0 is system (<font color='#ff0000'>requires restart</font>) - + show toolbar - + I don't need buttons - I know all keyboard shortcuts! - + nerd terminology - - Appearance (<font color='#ff0000'>requires restart</font>) + + Appearance - + Controls - + Startup @@ -361,47 +361,47 @@ Choose new library source: m8r::ConfigurationDialog::EditorTab - + Editor key binding - + Editor font - + Spell check dictionaries <a href='https://github.com/dvorka/mindforger/wiki/Installation#spell-check'>configuration documentation</a> - + live spell check - + TABs as SPACEs - + autosave Note on editor close - + TAB width - + External editor command - + Editor @@ -409,37 +409,37 @@ Choose new library source: m8r::ConfigurationDialog::MarkdownTab - + syntax highlighting - + autocomplete text - + autocomplete lists, blocks and {([`_ characters - + SPACE-based # in section escaping (HTML otherwise) - + Rendering - + Autocompletion - + Escaping @@ -447,22 +447,22 @@ Choose new library source: m8r::ConfigurationDialog::MindTab - + save reads metadata - + Async refresh interval (1 - 10.000ms) - + Persistence - + Notifications @@ -470,12 +470,12 @@ Choose new library source: m8r::ConfigurationDialog::NavigatorTab - + Max graph nodes (150 by default) - + Knowledge Graph Navigator @@ -483,101 +483,223 @@ Choose new library source: m8r::ConfigurationDialog::ViewerTab - + HTML Viewer - + Viewer theme CSS - + HTML zoom (100 is 100%, Ctrl + mouse wheel) - + source code syntax highlighting support - + math support - + whole notebook preview - + double click HTML preview to edit - + Diagram support - + Find Custom CSS File - + HTML Viewer CSS - + Choose CSS File - m8r::ConfigurationDialog::WingmanTab + m8r::ConfigurationDialog::WingmanOllamaTab - - LLM provider: + + <html><a href='https://ollama.com'>ollama</a> LLM provider configuration: +<ul><li>Set your ollama server URL - default is <a href='http://localhost:11434'>http://localhost:11434</a></li></ul> + + + + + <br>ollama server URL: + + + + + Set ollama as LLM Provider + + + + + Add ollama to the dropdown with LLM providers (if not there) and set it for use with Wingman + + + + + Refresh LLM models + + + + + Clear URL + + + + + LLM model: + + + + + LLM Provider Config Error + + + + + Unable to set ollama as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + + ollama Server URL Cleared + + + + + ollama server URL has been cleared from the configuration and ollama is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanOpenAiTab + + + <br>API key: + + + + + Refresh LLM models - - <html>Configure <a href='https://openai.com'>OpenAI</a> LLM provider: -<ul><li><a href='https://platform.openai.com/api-keys'>Generate</a> an OpenAI API key.</li><li>Set the API key:<br>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home dir.</li><li><font color='#ff0000'>Restart</font> MindForger to apply the change.</li></ul> + + Set OpenAI as LLM Provider - - Clear OpenAI API Key + + Add OpenAI to the dropdown with LLM providers (if not there) and set it for use with Wingman - + + Clear API Key + + + + + LLM model: + + + + + The OpenAI API key is configured using the environment<br/>variable <b>%1</b>.<br/>If you want to override it, then set the key below.<br/>It will be saved <font color='#ff0000'>unencrypted</font> to <b>.mindforger.md</b> configuration file in your home directory. + + + + + <html><a href='https://openai.com'>OpenAI</a> LLM provider configuration: +<ul><li>Generate new OpenAI API key at <a href='https://platform.openai.com/api-keys'>openai.com</a>.</li><li>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home directory.</li></ul> + + + + + The OpenAI API key is configured both using the environment<br/>variable <b>%1</b> and configuration.<br/>Configuration overrides environment - key from below is used. + + + + + The OpenAI API key is configured using the key below. + + + + + LLM Provider Config Error + + + + + Unable to set OpenAI as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + OpenAI API Key Cleared - - API key has been cleared from the configuration. Please close the configuration dialog with the OK button and restart MindForger to apply this change. + + API key has been cleared from the configuration and OpenAI is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanTab + + + LLM provider: - - Data Privacy Warning + + OpenAI - - You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers for GPT processing when you use Wingman. + + ollama + + + + + You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers when you use Wingman. + + + + + Data Privacy Warning - + Large language model (LLM) providers @@ -1110,18 +1232,18 @@ Choose new library source: - + S&cope - + Don't show Notebooks and Notes older than... - + &Forget @@ -1131,7 +1253,7 @@ Choose new library source: - + Retain @@ -1140,1078 +1262,1116 @@ Choose new library source: &Preferences - + Adapt Mind by setting your preferences... - + E&xit - + Leave application - + &Full-text Search - + Note full-text search - + Recall Note&book by Name - + Find Notebook by name - + Recall &Note by Name - + Find Note by name - + Find Notebook by tags - + Find Note by tags - + Recall Library &Doc by Name - + Find Document by name - + &Recall - + Open Home Notebook... - + N&otebooks - + Show list of Notebooks... - + Note&books Tree - + Show tree of Notebooks... - + &Tags - + Open Tag cloud... - + Knowledge Graph &Navigator - + Open knowledge graph Navigator... - + &Memory Dwell - + Open memory dwell... - + Ter&minal - + Run simple command line from current MindForger workspace... - + &Recent Notes - + View recently modified Notes... - + &Stencils - + List Notebook and Note stencils... - + List forgotten Notebooks and Notes... - + D&istraction Free - + Toggle distraction free mode - + &Fullscreen - + Toggle fullscreen - + &View - + Str&etch edges e | mouse wheel - + Stretch knowledge graph edges - + &Sh&rink edge E | mouse wheel - + Shring knowledge graph edges - + Zoom &in z - + Zoom in knowledge graph - + Zoom &out Z - + Zoom out knowledge graph - + &Shuffle Space - + Shuffle knowledge graph - + N&avigate - + &New library - + Add path to the directory with documents (PDF, txt, HTML)... - + &Update library - + Synchronize library source directory with MindForger notebook(s) which representlibrary resources... - + &Delete library - + Delete all Notebooks representing the library resources... - + &Edit ⌘↩ - + &Edit Alt-Enter - + Move Notebook/Note to Previous Column/Quadrant ⌘[ - + Move Notebook/Note to Next Column/Quadrant ⌘] - + Focus to Previous Column/Quadrant ⇧⇥ - + Focus to Next Column/Quadrant ⇥ - + &HTML - + Export Notebook to a file in HTML format - + &TWiki - + Import Notebook from an external TWiki file and restart MindForger - + &Undo Ctrl+Z - + Undo - + &Redo Ctrl+Shift+Z - + Redo - + Cu&t Ctrl+X - + Cut - + &Copy Ctrl+C - + Copy - + &Paste Ctrl+V - + Paste - - - - + + + + &Edit - + Create backup archive of the current workspace and store it in home directory - + Recall Note by T&ags - + Flashcard &Decks - + Show list of flashcard decks... - + Organiz&ers - + Open Eisenhower matrix and Kanban organizers... - + &Library Documents - + List Library documents... - + &Wingman - + Emo&jis - + Open dialog with emoji characters to be copy/pasted to names, descriptions and text... - + Li&mbo - - &Find on Web + + &Semantic Search + + + + + Use Wingman LLM to search for similar Notes (associations) using text embeddings... + + + + &Wingman LLM + + + + + &Find on Web + + + + Find Notebook or Note name; selected text or text under cursor on the web... - + Li&brary - + + &Find orphans + + + + + Find library Notebooks which reference non-existent documents... + + + + + Deprecate &orphans + + + + + Deprecate library Notebooks that has tag which indicates reference of non-existent document... + + + + &CLI - + Ho&ist - + Str&etch edges - + &Sh&rink edge - + Flash&cards - + &Organizer - + Create new Organizer to prioritize your knowledge in Eisenhower Matrix style - + Edit current Organizer - you can also double click view to open the editor - + Make copy of the current Organizer - + &Delete - + Delete Organizer without undo - - + + Move Notebook/Note to &Previous Column/Quadrant Ctrl+Left - + Move Notebook/Note to previous column or quadrant... - - + + Move Notebook/Note to Ne&xt Column/Quadrant Ctrl+Right - + Move Notebook/Note to next column or quadrant... - + Note&book - + E&xamine - + Turn Notebook to deck of flashcard and start active recall testing... - + &Promote - + Promote Notebook - + De&mote - + Demote Notebook - + Move to &First - + Move the Notebook to be the first child of its parent - + Move &Up - + Move the Notebook up - + Move the Notebook down - + Move to &Last - + Move the Notebook to be the last child of its parent - + E&xternal Editor Edit Ctrl+X - + Edit current Note in an external editor - use Preferences to configure the editor - + &Forget Ctrl+D - + Save and Leave Ctrl+L - + Move to F&irst Ctrl+Shift+Up - + Move the Note to be the first child of its parent - + Move &Up Ctrl+Up - + Move the Note up - + Move the Note down - + Move to &Last Ctrl+Shift+Down - + Move the Note to be the last child of its parent - + Move to Notebook Ctrl+R - + &Move to Notebook - + Move the current Note to another Notebook... - + &Find Ctrl+Shift+F - + &Live Preview - + Toggle live HTML preview - + Swap focus of N title and description editors - + Run an external tool to find, explain, process text under the cursor - + Complete Link Ctrl+L - + Spell check Notebook or Note description - + &Bold - + Format text as bold - + &Italic - + Format text as italic - + &Code - + Format text as inlined source code - + Comment - + Add comment to hide text in rendered HTML - + Lis&ts - + &Bulleted List - + &Numbered List - + &Task List - + Task List &Item - + Bl&ocks - + &Code Block - + &Math Block - + &Diagram Block - + Format code block as diagram (Mermaid) - + Diagrams - + &Flowchart - + Insert flowchart Mermaid diagram skeleton - + &Sequence Diagram - + Insert sequence Mermaid diagram skeleton - + &Class Diagram - + Insert class Mermaid diagram skeleton - + St&ate Diagram - + Insert state Mermaid diagram skeleton - + &Gantt Diagram - + Insert Gantt Mermaid diagram skeleton - + &Pie Diagram - + Insert pie Mermaid chart skeleton - + in&tegrals - + dot - + ca&p - + in - + &Strikethrough - + Format text as strikethrough - + About &Qt - + &Keyboard - + Format text as keyboard input - + Math cheatsheet - + Open MathJax quick reference - + Math live preview - + Open MathJax live demo - + Mermaid dia&grams documentation - + Open Mermaid diagrams documentation - + Format block as bulleted list - + Format block as numbered list - - + + Format block as task list - + Format text block as source code - + Block &Quote - + Format text block as blockquote - + Timestam&p - + &Link - + Insert link to a document, image or file - + Insert image - + Tabl&es - + &Horizontal ruler - + Horizontal ruler - + &Format - - - - + + + + &New - + Create new Notebook to form new ideas, principles, combinations or applications - + Edit current Notebook - you can also double click view to open the editor - + Make &Home - + Import - - + + Make &Stencil - - + + Copy the current Notebook as to Stencil - + C&lone - + Make copy of the current Notebook - + Forget Notebook and move it to Limbo - + E&xport - + &Forget Del - + Forget Note @@ -2221,12 +2381,12 @@ Choose new library source: - + Toggle tag indicating whether to use the current Notebook as home - + &Import @@ -2246,108 +2406,108 @@ Choose new library source: - + A&dapt - + &CSV - + Export all Notebooks/Markdown files as a single CSV file - + Recall Notebook by Ta&gs - + &Home Notebook - + Activate command line interface... - + Create new Note to form new ideas, principles, combinations and applications - + Hoist/de-hoist Note to focus on Note being viewed or edited - + &Edit Ctrl+E - + Edit current Note - you can also double click view to open the editor - + Remember Ctrl+S - + Save Note being edited - + Leave Alt+Left - + Save leave editor of Note being changed - + &Promote Ctrl+Left - + Promote Note - + &Demote Ctrl+Right - + Demote Note - + E&xtract - + Create new Note from the text selected in the current Note... - - + + &Clone @@ -2388,411 +2548,403 @@ Choose new library source: - + Make a copy of the Note to this or other Notebook... - + Export Note to an external file in a supported format - + Import Note from an external file in a supported format - + &Note - - - - - &Wingman GPT - - - - + Open Wingman dialog... - + Move focus to previous column or quadrant... - + Move focus to next column or quadrant... - + Move D&own - - + + &Summarize - + Ask Wingman to summarize text of the Notebook... - - + + &Explain - + Ask Wingman to explain the name of the Notebook... - + &Find Tasks - + Ask Wingman to find tasks in the Notebook text... - - - + + + &More prompts... - - - + + + Open Wingman chat... - + Move Dow&n Ctrl+Down - + Ask Wingman to summarize text of the Note... - + &Find Grammar Errors - + Ask Wingman to find grammar errors in the Note text... - + &Translate to English - + Ask Wingman to translate the Note text to English... - + Search Note text - + Find Next Ctrl+F - + Search Note text again - + W&ord Wrap - + Toggle word wrap mode - + Swap Nam&e/Description Focus - + Complete word being written by finding link to Notebook or Note - + &Spell Check - + &Fix Grammar - + Ask Wingman to fix grammar errors in the selected text / word under the cursor... - + Ask Wingman to explain the word under the cursor / selected text... - + Finish &Text - + Ask Wingman to finish the text following the selected text / word under the cursor... - + &Rewrite Text - + Ask Wingman to rewrite the text following the selected text / word under the cursor... - + &Math - + Format text as math (MathJax) - + MathJa&x - + &text - + &fraction - + &sum - + s&quare root - + &integral - + &alpha - + &beta - + &Gama - + &Delta - + &bar - + &hat - + &overrightarrow - + &cup - + &empty set - + &not in - + T&able of Contents - + Insert current date and time - + Format text block as math (MathJax) - + With&out tags - + Insert Notebook's table of contents without tags - + &With tags - + Insert Notebook's table of contents with tags - + Ima&ge - + Insert table... - + &Documentation - + F1 - + Open MindForger documentation - + &Web - + Open MindForger web - + &Markdown tutorial - + Open Markdown tutorial - + Report &Bug or Request Feature - + Report bug or suggest an enhancement - + &Check for Updates - + Check for MindForger updates - + About Qt... - + &About MindForger - + About MindForger... - + &Help @@ -2869,8 +3021,8 @@ Choose new library source: - - + + Specified file path already exists! @@ -2924,7 +3076,7 @@ Choose new library source: - + Notebook @@ -3019,181 +3171,166 @@ Choose new library source: - - Wingman is talking to the GPT provider... - - - - - Wingman received an answer from the GPT provider - - - - - Wingman failed to receive an answer from the GPT provider - - - - - + + Wingman Action Error - + Wingman's answer appended after selected text in the Note editor. - + Unable to append after selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to append after selected text - run a prompt. - + Wingman's answer replaced selected text in Notebook header. - + Unable to replace Notebook header text - no text selected. - + Wingman's answer replaced selected text in Note text. - + Unable to replace Note text - no text selected. - + Unable to replace selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to replace selected text - run a prompt. - + Edit Notebook - + Please open an Notebook to edit. - - + + New Note - + Failed to create new Note! - - + + Clone Notebook - + Failed to clone Notebook! - + Please open and Notebook to be cloned. - + Home tag toggled/removed - Notebook '%1' is no longer home - + Notebook '%1' successfully marked as home - + Make Notebook home - + Notebook can be marked as home only when viewed. - - + + Forget Notebook - + Library already indexed - use 'Update library' action to synchronize documents. - + Unable to index documents on library path - either memory directory doesn't exist or not in MindForger workspace mode. - + Library synchronization - + There are no libraries - nothing to synchronize. - + Library deletion - + There are no libraries - nothing to delete. - + Delete Library - + Do you really want to delete Notebooks which represent the library documents? - + Do you really want to forget ' - + ' Notebook? @@ -3264,310 +3401,353 @@ Choose new library source: - + + Wingman is runnning inferences... + + + + + Wingman received an answer from the LLM provider + + + + + Wingman failed to receive an answer from the LLM provider + + + + Wingman's answer appended after selected text in the Notebook header. - + Wingman's answer appended after the cursor in the Notebook header. - + Wingman's answer appended after the cursor in the Note editor. - + 🔒 Notebook Write Error - + Notebook file is read-only and cannot be written: '%1' - + Do you really want to deprecate ' - + Notebook can be forgotten only when viewed. - - - + + + Export Error - + Unable to find Notebook to export! - + Import TWiki File - + Open and view a Notebook to create new Note. - + Edit Note - - + + Please select a Note to edit in the Notebook. - - + + Edit Note with External Editor Error - + External editor command is not configured in preferences (Editor tab). - - + + Edit Note with External Editor - + Running command: '%1' - + Running command: '%1'. Close external editor to return control back to MindForger. - + Delete Note - + Do you really want to delete note ' - + ' along with its child notes? - + Forget Note - + Please select a Note to forget. - - - + + + Extract Note - + Please select a text to extract. - + Failed to extract new Note! - + Please select a Note, edit it and select a text to extract. - - - + + + Clone Note - + Do you want to clone Note ' - + ' including its child notes?'? - + Failed to clone Note! - + Please select a Note to be cloned. - + Moved Note '%1' to be the first child - - - - + + + + Move Note - - - - + + + + Please select a Note to be moved. - + Moved up Note '%1' - + Moved down Note '%1' - + Moved Note '%1' to be the last child - + Promoted Note '%1' - + Promote Note - + Please select a Note to be promoted. - + Demoted Note '%1' - + Demote Note - + Please select a Note to be demoted. - - - + + + Add Library Error - + Library directory doesn't exist! - + + + + + Library Orphans + + + + + Found %1 library Notebooks with orphaned documents. Notebooks were tagged with 'library-orphan-document' tag. Use scopes to filter them out. + + + + + No Notebooks with orphaned documents found. + + + + + %1 Notebooks tagged as library orphans were deprecated. + + + + + No Notebooks with library orphan tag found. + + + + Organizer Update Error - + Eisenhower Matrix organizer is built-in and cannot be edited - please create or update a custom organizer. - + Organizer Clone Error - + Eisenhower Matrix organizer is built-in and cannot be cloned - please create or update a custom organizer. - + Forget Organizer - + ' Organizer? - + Delete Organizer - + Eisenhower Matrix is built-in and cannot be deleted - only custom organizers can. - + View Limbo - + Limbo directory with deleted Notebooks is available in the MindForger workspace, not if a Markdown is edited or a directory with markdowns is opened. - + Emojis - + About MindForger @@ -3575,7 +3755,7 @@ Choose new library source: m8r::MainWindowView - + Thinking Notebook diff --git a/app/resources/qt/translations/mindforger_en.qm b/app/resources/qt/translations/mindforger_en.qm index 7a14041a..3385a8e3 100644 Binary files a/app/resources/qt/translations/mindforger_en.qm and b/app/resources/qt/translations/mindforger_en.qm differ diff --git a/app/resources/qt/translations/mindforger_en.ts b/app/resources/qt/translations/mindforger_en.ts index 94f4875c..958a6c87 100644 --- a/app/resources/qt/translations/mindforger_en.ts +++ b/app/resources/qt/translations/mindforger_en.ts @@ -309,52 +309,52 @@ Choose new library source: m8r::ConfigurationDialog::AppTab - + UI theme (<font color='#ff0000'>requires restart</font>) - + Menu (<font color='#ff0000'>requires restart</font>) - + Show the following view on application start - + Application font size - 0 is system (<font color='#ff0000'>requires restart</font>) - + show toolbar - + I don't need buttons - I know all keyboard shortcuts! - + nerd terminology - - Appearance (<font color='#ff0000'>requires restart</font>) + + Appearance - + Controls - + Startup @@ -362,47 +362,47 @@ Choose new library source: m8r::ConfigurationDialog::EditorTab - + Editor key binding - + Editor font - + Spell check dictionaries <a href='https://github.com/dvorka/mindforger/wiki/Installation#spell-check'>configuration documentation</a> - + live spell check - + TABs as SPACEs - + autosave Note on editor close - + TAB width - + External editor command - + Editor @@ -410,37 +410,37 @@ Choose new library source: m8r::ConfigurationDialog::MarkdownTab - + syntax highlighting - + autocomplete text - + autocomplete lists, blocks and {([`_ characters - + SPACE-based # in section escaping (HTML otherwise) - + Rendering - + Autocompletion - + Escaping @@ -448,22 +448,22 @@ Choose new library source: m8r::ConfigurationDialog::MindTab - + save reads metadata - + Async refresh interval (1 - 10.000ms) - + Persistence - + Notifications @@ -471,12 +471,12 @@ Choose new library source: m8r::ConfigurationDialog::NavigatorTab - + Max graph nodes (150 by default) - + Knowledge Graph Navigator @@ -484,101 +484,223 @@ Choose new library source: m8r::ConfigurationDialog::ViewerTab - + HTML Viewer - + Viewer theme CSS - + HTML zoom (100 is 100%, Ctrl + mouse wheel) - + source code syntax highlighting support - + math support - + whole notebook preview - + double click HTML preview to edit - + Diagram support - + Find Custom CSS File - + HTML Viewer CSS - + Choose CSS File - m8r::ConfigurationDialog::WingmanTab + m8r::ConfigurationDialog::WingmanOllamaTab - - LLM provider: + + <html><a href='https://ollama.com'>ollama</a> LLM provider configuration: +<ul><li>Set your ollama server URL - default is <a href='http://localhost:11434'>http://localhost:11434</a></li></ul> + + + + + <br>ollama server URL: + + + + + Set ollama as LLM Provider + + + + + Add ollama to the dropdown with LLM providers (if not there) and set it for use with Wingman + + + + + Refresh LLM models + + + + + Clear URL + + + + + LLM model: + + + + + LLM Provider Config Error + + + + + Unable to set ollama as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + + ollama Server URL Cleared + + + + + ollama server URL has been cleared from the configuration and ollama is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanOpenAiTab + + + <br>API key: + + + + + Refresh LLM models - - <html>Configure <a href='https://openai.com'>OpenAI</a> LLM provider: -<ul><li><a href='https://platform.openai.com/api-keys'>Generate</a> an OpenAI API key.</li><li>Set the API key:<br>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home dir.</li><li><font color='#ff0000'>Restart</font> MindForger to apply the change.</li></ul> + + Set OpenAI as LLM Provider - - Clear OpenAI API Key + + Add OpenAI to the dropdown with LLM providers (if not there) and set it for use with Wingman - + + Clear API Key + + + + + LLM model: + + + + + The OpenAI API key is configured using the environment<br/>variable <b>%1</b>.<br/>If you want to override it, then set the key below.<br/>It will be saved <font color='#ff0000'>unencrypted</font> to <b>.mindforger.md</b> configuration file in your home directory. + + + + + <html><a href='https://openai.com'>OpenAI</a> LLM provider configuration: +<ul><li>Generate new OpenAI API key at <a href='https://platform.openai.com/api-keys'>openai.com</a>.</li><li>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home directory.</li></ul> + + + + + The OpenAI API key is configured both using the environment<br/>variable <b>%1</b> and configuration.<br/>Configuration overrides environment - key from below is used. + + + + + The OpenAI API key is configured using the key below. + + + + + LLM Provider Config Error + + + + + Unable to set OpenAI as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + OpenAI API Key Cleared - - API key has been cleared from the configuration. Please close the configuration dialog with the OK button and restart MindForger to apply this change. + + API key has been cleared from the configuration and OpenAI is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanTab + + + LLM provider: - - Data Privacy Warning + + OpenAI - - You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers for GPT processing when you use Wingman. + + ollama + + + + + You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers when you use Wingman. + + + + + Data Privacy Warning - + Large language model (LLM) providers @@ -1117,7 +1239,7 @@ Choose new library source: Re&member - &Save + Save @@ -1130,18 +1252,18 @@ Choose new library source: - + S&cope - + Don't show Notebooks and Notes older than... - + &Forget &Deprecate @@ -1151,7 +1273,7 @@ Choose new library source: - + Retain Reta&in @@ -1160,47 +1282,47 @@ Choose new library source: &Preferences - + Adapt Mind by setting your preferences... - + E&xit - + Leave application - + &Full-text Search - + Note full-text search - + Recall Note&book by Name Find Note&book by Name - + Find Notebook by name - + Recall &Note by Name Find &Note by Name - + Find Note by name @@ -1209,7 +1331,7 @@ Choose new library source: Find Notebook by T&ags - + Find Notebook by tags @@ -1218,17 +1340,17 @@ Choose new library source: Find Note by &Tags - + Find Note by tags - + Recall Library &Doc by Name Find Library &Doc by Name - + Find Document by name @@ -1249,1048 +1371,1086 @@ Choose new library source: Find Other Entities - + &Recall F&ind - + Open Home Notebook... - + N&otebooks - + Show list of Notebooks... - + Note&books Tree - + Show tree of Notebooks... - + &Tags - + Open Tag cloud... - + Knowledge Graph &Navigator - + Open knowledge graph Navigator... - + &Memory Dwell - + Open memory dwell... - + Ter&minal - + Run simple command line from current MindForger workspace... - + &Recent Notes - + View recently modified Notes... - + &Stencils - + List Notebook and Note stencils... - + List forgotten Notebooks and Notes... - + D&istraction Free - + Toggle distraction free mode - + &Fullscreen - + Toggle fullscreen - + &View - + Str&etch edges e | mouse wheel - + Stretch knowledge graph edges - + &Sh&rink edge E | mouse wheel - + Shring knowledge graph edges - + Zoom &in z - + Zoom in knowledge graph - + Zoom &out Z - + Zoom out knowledge graph - + &Shuffle Space - + Shuffle knowledge graph - + N&avigate - + &New library - + Add path to the directory with documents (PDF, txt, HTML)... - + &Update library - + Synchronize library source directory with MindForger notebook(s) which representlibrary resources... - + &Delete library - + Delete all Notebooks representing the library resources... - + &Edit ⌘↩ - + &Edit Alt-Enter - + Move Notebook/Note to Previous Column/Quadrant ⌘[ - + Move Notebook/Note to Next Column/Quadrant ⌘] - + Focus to Previous Column/Quadrant ⇧⇥ - + Focus to Next Column/Quadrant ⇥ - + &HTML - + Export Notebook to a file in HTML format - + &TWiki - + Import Notebook from an external TWiki file and restart MindForger - + Search Note text - + Find Next Ctrl+F - + Search Note text again - + &Undo Ctrl+Z - + Undo - + &Redo Ctrl+Shift+Z - + Redo - + Cu&t Ctrl+X - + Cut - + &Copy Ctrl+C - + Copy - + &Paste Ctrl+V - + Paste - - - - + + + + &Edit - + Create backup archive of the current workspace and store it in home directory - + Recall Note by T&ags Find Note by T&ags - + Flashcard &Decks - + Show list of flashcard decks... - + Organiz&ers - + Open Eisenhower matrix and Kanban organizers... - + &Library Documents - + List Library documents... - + &Wingman - + Emo&jis - + Open dialog with emoji characters to be copy/pasted to names, descriptions and text... - + Li&mbo - - &Find on Web + + &Semantic Search + + + + + Use Wingman LLM to search for similar Notes (associations) using text embeddings... + + + + &Wingman LLM + + + + + &Find on Web + + + + Find Notebook or Note name; selected text or text under cursor on the web... - + Li&brary - + + &Find orphans + + + + + Find library Notebooks which reference non-existent documents... + + + + + Deprecate &orphans + + + + + Deprecate library Notebooks that has tag which indicates reference of non-existent document... + + + + &CLI - + Ho&ist - + Str&etch edges - + &Sh&rink edge - + Flash&cards - + &Organizer - + Create new Organizer to prioritize your knowledge in Eisenhower Matrix style - + Edit current Organizer - you can also double click view to open the editor - + Make copy of the current Organizer - + &Delete - + Delete Organizer without undo - - + + Move Notebook/Note to &Previous Column/Quadrant Ctrl+Left - + Move Notebook/Note to previous column or quadrant... - - + + Move Notebook/Note to Ne&xt Column/Quadrant Ctrl+Right - + Move Notebook/Note to next column or quadrant... - + Note&book - + E&xamine - + Turn Notebook to deck of flashcard and start active recall testing... - + &Promote - + Promote Notebook - + De&mote - + Demote Notebook - + Move to &First - + Move the Notebook to be the first child of its parent - + Move &Up - + Move the Notebook up - + Move the Notebook down - + Move to &Last - + Move the Notebook to be the last child of its parent - + E&xternal Editor Edit Ctrl+X - + Edit current Note in an external editor - use Preferences to configure the editor - + &Forget Ctrl+D - + Save and Leave Ctrl+L - + Move to F&irst Ctrl+Shift+Up - + Move the Note to be the first child of its parent - + Move &Up Ctrl+Up - + Move the Note up - + Move the Note down - + Move to &Last Ctrl+Shift+Down - + Move the Note to be the last child of its parent - + Move to Notebook Ctrl+R - + &Move to Notebook - + Move the current Note to another Notebook... - + &Find Ctrl+Shift+F - + &Live Preview - + Toggle live HTML preview - + Swap focus of N title and description editors - + Run an external tool to find, explain, process text under the cursor - + Complete Link Ctrl+L - + Spell check Notebook or Note description - + &Bold - + Format text as bold - + &Italic - + Format text as italic - + &Code - + Format text as inlined source code - + &Math - + Format text as math (MathJax) - + Comment - + Add comment to hide text in rendered HTML - + Lis&ts - + &Bulleted List - + &Numbered List - + &Task List - + Task List &Item - + Bl&ocks - + &Code Block - + &Math Block - + &Diagram Block - + Format code block as diagram (Mermaid) - + Diagrams - + &Flowchart - + Insert flowchart Mermaid diagram skeleton - + &Sequence Diagram - + Insert sequence Mermaid diagram skeleton - + &Class Diagram - + Insert class Mermaid diagram skeleton - + St&ate Diagram - + Insert state Mermaid diagram skeleton - + &Gantt Diagram - + Insert Gantt Mermaid diagram skeleton - + &Pie Diagram - + Insert pie Mermaid chart skeleton - + in&tegrals - + dot - + ca&p - + in - + &Strikethrough - + Format text as strikethrough - + About &Qt - + &Keyboard - + Format text as keyboard input - + Math cheatsheet - + Open MathJax quick reference - + Math live preview - + Open MathJax live demo - + Mermaid dia&grams documentation - + Open Mermaid diagrams documentation - + Format block as bulleted list - + Format block as numbered list - - + + Format block as task list - + T&able of Contents - + Insert current date and time - + Format text block as source code - + Format text block as math (MathJax) - + Block &Quote - + Format text block as blockquote - + &Link - + Insert link to a document, image or file - + Insert image - + Tabl&es - + &Horizontal ruler - + Horizontal ruler - + &Format - - - - + + + + &New - + Create new Notebook to form new ideas, principles, combinations or applications - + Edit current Notebook - you can also double click view to open the editor - + Make &Home - + Import - - + + Make &Stencil - - + + Copy the current Notebook as to Stencil - + C&lone - + Make copy of the current Notebook - + Forget Notebook and move it to Limbo Delete Notebook and move it Limbo - + E&xport - + &Forget Del Delete Del - + Forget Note Delete Note @@ -2300,12 +2460,12 @@ Choose new library source: &Open - + Toggle tag indicating whether to use the current Notebook as home - + &Import @@ -2325,108 +2485,108 @@ Choose new library source: - + A&dapt &Preferences - + &CSV - + Export all Notebooks/Markdown files as a single CSV file - + Recall Notebook by Ta&gs Find Notebook by Ta&gs - + &Home Notebook - + Activate command line interface... - + Create new Note to form new ideas, principles, combinations and applications - + Hoist/de-hoist Note to focus on Note being viewed or edited - + &Edit Ctrl+E - + Edit current Note - you can also double click view to open the editor - + Remember Ctrl+S Save Ctrl+S - + Save Note being edited - + Leave Alt+Left - + Save leave editor of Note being changed - + &Promote Ctrl+Left - + Promote Note - + &Demote Ctrl+Right - + Demote Note - + E&xtract - + Create new Note from the text selected in the current Note... - - + + &Clone @@ -2467,376 +2627,368 @@ Choose new library source: - + Make a copy of the Note to this or other Notebook... - + Export Note to an external file in a supported format - + Import Note from an external file in a supported format - + &Note - - - - - &Wingman GPT - - - - + Open Wingman dialog... - + Move focus to previous column or quadrant... - + Move focus to next column or quadrant... - + Move D&own - - + + &Summarize - + Ask Wingman to summarize text of the Notebook... - - + + &Explain - + Ask Wingman to explain the name of the Notebook... - + &Find Tasks - + Ask Wingman to find tasks in the Notebook text... - - - + + + &More prompts... - - - + + + Open Wingman chat... - + Move Dow&n Ctrl+Down - + Ask Wingman to summarize text of the Note... - + &Find Grammar Errors - + Ask Wingman to find grammar errors in the Note text... - + &Translate to English - + Ask Wingman to translate the Note text to English... - + W&ord Wrap - + Toggle word wrap mode - + Swap Nam&e/Description Focus - + Complete word being written by finding link to Notebook or Note - + &Spell Check - + &Fix Grammar - + Ask Wingman to fix grammar errors in the selected text / word under the cursor... - + Ask Wingman to explain the word under the cursor / selected text... - + Finish &Text - + Ask Wingman to finish the text following the selected text / word under the cursor... - + &Rewrite Text - + Ask Wingman to rewrite the text following the selected text / word under the cursor... - + MathJa&x - + &text - + &fraction - + &sum - + s&quare root - + &integral - + &alpha - + &beta - + &Gama - + &Delta - + &bar - + &hat - + &overrightarrow - + &cup - + &empty set - + &not in - + With&out tags - + Insert Notebook's table of contents without tags - + &With tags - + Insert Notebook's table of contents with tags - + Timestam&p - + Ima&ge - + Insert table... - + &Documentation - + F1 - + Open MindForger documentation - + &Web - + Open MindForger web - + &Markdown tutorial - + Open Markdown tutorial - + Report &Bug or Request Feature - + Report bug or suggest an enhancement - + &Check for Updates - + Check for MindForger updates - + About Qt... - + &About MindForger - + About MindForger... - + &Help @@ -2913,8 +3065,8 @@ Choose new library source: - - + + Specified file path already exists! @@ -2972,7 +3124,7 @@ Choose new library source: - + Notebook @@ -3067,181 +3219,166 @@ Choose new library source: - - Wingman is talking to the GPT provider... - - - - - Wingman received an answer from the GPT provider - - - - - Wingman failed to receive an answer from the GPT provider - - - - - + + Wingman Action Error - + Wingman's answer appended after selected text in the Note editor. - + Unable to append after selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to append after selected text - run a prompt. - + Wingman's answer replaced selected text in Notebook header. - + Unable to replace Notebook header text - no text selected. - + Wingman's answer replaced selected text in Note text. - + Unable to replace Note text - no text selected. - + Unable to replace selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to replace selected text - run a prompt. - + Edit Notebook - + Please open an Notebook to edit. - - + + New Note - + Failed to create new Note! - - + + Clone Notebook - + Failed to clone Notebook! - + Please open and Notebook to be cloned. - + Home tag toggled/removed - Notebook '%1' is no longer home - + Notebook '%1' successfully marked as home - + Make Notebook home - + Notebook can be marked as home only when viewed. - - + + Forget Notebook Deprecate Notebook - + Library already indexed - use 'Update library' action to synchronize documents. - + Unable to index documents on library path - either memory directory doesn't exist or not in MindForger workspace mode. - + Library synchronization - + There are no libraries - nothing to synchronize. - + Library deletion - + There are no libraries - nothing to delete. - + Delete Library - + Do you really want to delete Notebooks which represent the library documents? - + Do you really want to forget ' - + ' Notebook? @@ -3312,310 +3449,353 @@ Choose new library source: - + + Wingman is runnning inferences... + + + + + Wingman received an answer from the LLM provider + + + + + Wingman failed to receive an answer from the LLM provider + + + + Wingman's answer appended after selected text in the Notebook header. - + Wingman's answer appended after the cursor in the Notebook header. - + Wingman's answer appended after the cursor in the Note editor. - + 🔒 Notebook Write Error - + Notebook file is read-only and cannot be written: '%1' - + Do you really want to deprecate ' - + Notebook can be forgotten only when viewed. - - - + + + Export Error - + Unable to find Notebook to export! - + Import TWiki File - + Open and view a Notebook to create new Note. - + Edit Note - - + + Please select a Note to edit in the Notebook. - - + + Edit Note with External Editor Error - + External editor command is not configured in preferences (Editor tab). - - + + Edit Note with External Editor - + Running command: '%1' - + Running command: '%1'. Close external editor to return control back to MindForger. - + Delete Note - + Do you really want to delete note ' - + ' along with its child notes? - + Forget Note Delete Note - + Please select a Note to forget. Please select a Note to delete. - - - + + + Extract Note - + Please select a text to extract. - + Failed to extract new Note! - + Please select a Note, edit it and select a text to extract. - - - + + + Clone Note - + Do you want to clone Note ' - + ' including its child notes?'? - + Failed to clone Note! - + Please select a Note to be cloned. - + Moved Note '%1' to be the first child - - - - + + + + Move Note - - - - + + + + Please select a Note to be moved. - + Moved up Note '%1' - + Moved down Note '%1' - + Moved Note '%1' to be the last child - + Promoted Note '%1' - + Promote Note - + Please select a Note to be promoted. - + Demoted Note '%1' - + Demote Note - + Please select a Note to be demoted. - - - + + + Add Library Error - + Library directory doesn't exist! - + + + + + Library Orphans + + + + + Found %1 library Notebooks with orphaned documents. Notebooks were tagged with 'library-orphan-document' tag. Use scopes to filter them out. + + + + + No Notebooks with orphaned documents found. + + + + + %1 Notebooks tagged as library orphans were deprecated. + + + + + No Notebooks with library orphan tag found. + + + + Organizer Update Error - + Eisenhower Matrix organizer is built-in and cannot be edited - please create or update a custom organizer. - + Organizer Clone Error - + Eisenhower Matrix organizer is built-in and cannot be cloned - please create or update a custom organizer. - + Forget Organizer - + ' Organizer? - + Delete Organizer - + Eisenhower Matrix is built-in and cannot be deleted - only custom organizers can. - + View Limbo - + Limbo directory with deleted Notebooks is available in the MindForger workspace, not if a Markdown is edited or a directory with markdowns is opened. - + Emojis - + About MindForger @@ -3623,7 +3803,7 @@ Choose new library source: m8r::MainWindowView - + Thinking Notebook diff --git a/app/resources/qt/translations/mindforger_nerd_cs.qm b/app/resources/qt/translations/mindforger_nerd_cs.qm index d2cbc20d..19927825 100644 Binary files a/app/resources/qt/translations/mindforger_nerd_cs.qm and b/app/resources/qt/translations/mindforger_nerd_cs.qm differ diff --git a/app/resources/qt/translations/mindforger_nerd_cs.ts b/app/resources/qt/translations/mindforger_nerd_cs.ts index 9504fdee..94193905 100644 --- a/app/resources/qt/translations/mindforger_nerd_cs.ts +++ b/app/resources/qt/translations/mindforger_nerd_cs.ts @@ -316,52 +316,52 @@ Choose new library source: m8r::ConfigurationDialog::AppTab - + UI theme (<font color='#ff0000'>requires restart</font>) - + Menu (<font color='#ff0000'>requires restart</font>) - + Show the following view on application start - + Application font size - 0 is system (<font color='#ff0000'>requires restart</font>) - + show toolbar - + I don't need buttons - I know all keyboard shortcuts! - + nerd terminology - - Appearance (<font color='#ff0000'>requires restart</font>) + + Appearance - + Controls - + Startup @@ -369,47 +369,47 @@ Choose new library source: m8r::ConfigurationDialog::EditorTab - + Editor key binding - + Editor font - + Spell check dictionaries <a href='https://github.com/dvorka/mindforger/wiki/Installation#spell-check'>configuration documentation</a> - + live spell check - + TABs as SPACEs - + autosave Note on editor close - + TAB width - + External editor command - + Editor @@ -417,37 +417,37 @@ Choose new library source: m8r::ConfigurationDialog::MarkdownTab - + syntax highlighting - + autocomplete text - + autocomplete lists, blocks and {([`_ characters - + SPACE-based # in section escaping (HTML otherwise) - + Rendering - + Autocompletion - + Escaping @@ -455,22 +455,22 @@ Choose new library source: m8r::ConfigurationDialog::MindTab - + save reads metadata - + Async refresh interval (1 - 10.000ms) - + Persistence - + Notifications @@ -478,12 +478,12 @@ Choose new library source: m8r::ConfigurationDialog::NavigatorTab - + Max graph nodes (150 by default) - + Knowledge Graph Navigator @@ -491,101 +491,223 @@ Choose new library source: m8r::ConfigurationDialog::ViewerTab - + HTML Viewer - + Viewer theme CSS - + HTML zoom (100 is 100%, Ctrl + mouse wheel) - + source code syntax highlighting support - + math support - + whole notebook preview - + double click HTML preview to edit - + Diagram support - + Find Custom CSS File - + HTML Viewer CSS - + Choose CSS File - m8r::ConfigurationDialog::WingmanTab + m8r::ConfigurationDialog::WingmanOllamaTab - - LLM provider: + + <html><a href='https://ollama.com'>ollama</a> LLM provider configuration: +<ul><li>Set your ollama server URL - default is <a href='http://localhost:11434'>http://localhost:11434</a></li></ul> + + + + + <br>ollama server URL: + + + + + Set ollama as LLM Provider + + + + + Add ollama to the dropdown with LLM providers (if not there) and set it for use with Wingman + + + + + Refresh LLM models + + + + + Clear URL + + + + + LLM model: + + + + + LLM Provider Config Error + + + + + Unable to set ollama as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + + ollama Server URL Cleared + + + + + ollama server URL has been cleared from the configuration and ollama is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanOpenAiTab + + + <br>API key: + + + + + Refresh LLM models - - <html>Configure <a href='https://openai.com'>OpenAI</a> LLM provider: -<ul><li><a href='https://platform.openai.com/api-keys'>Generate</a> an OpenAI API key.</li><li>Set the API key:<br>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home dir.</li><li><font color='#ff0000'>Restart</font> MindForger to apply the change.</li></ul> + + Set OpenAI as LLM Provider - - Clear OpenAI API Key + + Add OpenAI to the dropdown with LLM providers (if not there) and set it for use with Wingman - + + Clear API Key + + + + + LLM model: + + + + + The OpenAI API key is configured using the environment<br/>variable <b>%1</b>.<br/>If you want to override it, then set the key below.<br/>It will be saved <font color='#ff0000'>unencrypted</font> to <b>.mindforger.md</b> configuration file in your home directory. + + + + + <html><a href='https://openai.com'>OpenAI</a> LLM provider configuration: +<ul><li>Generate new OpenAI API key at <a href='https://platform.openai.com/api-keys'>openai.com</a>.</li><li>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home directory.</li></ul> + + + + + The OpenAI API key is configured both using the environment<br/>variable <b>%1</b> and configuration.<br/>Configuration overrides environment - key from below is used. + + + + + The OpenAI API key is configured using the key below. + + + + + LLM Provider Config Error + + + + + Unable to set OpenAI as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + OpenAI API Key Cleared - - API key has been cleared from the configuration. Please close the configuration dialog with the OK button and restart MindForger to apply this change. + + API key has been cleared from the configuration and OpenAI is no longer the LLM provider. + + + m8r::ConfigurationDialog::WingmanTab - - Data Privacy Warning + + LLM provider: - - You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers for GPT processing when you use Wingman. + + OpenAI + + + + + ollama + + + + + You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers when you use Wingman. + + + + + Data Privacy Warning - + Large language model (LLM) providers @@ -1082,10 +1204,10 @@ Choose new library source: - - - - + + + + &New &Nový @@ -1100,7 +1222,7 @@ Choose new library source: - + &Recall @@ -1115,7 +1237,7 @@ Choose new library source: - + &Forget Zapomeň @@ -1125,17 +1247,17 @@ Choose new library source: - + Adapt Mind by setting your preferences... - + E&xit Konec - + Leave application @@ -1145,27 +1267,27 @@ Choose new library source: &Mysl - + &Full-text Search - + Note full-text search - + Recall &Note by Name - + Find Note by name - + Find Note by tags @@ -1174,564 +1296,577 @@ Choose new library source: Domů - + &Memory Dwell - + &Recent Notes - + &Stencils - + Don't show Notebooks and Notes older than... - + + &Semantic Search + + + + + + + + &Wingman LLM + + + + Create backup archive of the current workspace and store it in home directory - + Find Notebook by name - + Find Notebook by tags - + Recall Note by T&ags - + Flashcard &Decks - + Show list of flashcard decks... - + Organiz&ers - + Open Eisenhower matrix and Kanban organizers... - + N&otebooks - + &Library Documents - + List Library documents... - + &CLI - + Li&mbo - + Ho&ist - + Toggle distraction free mode - + &Fullscreen - + &View - + Str&etch edges - + &Sh&rink edge - + Flash&cards - + &Organizer - + Create new Organizer to prioritize your knowledge in Eisenhower Matrix style - + Edit current Organizer - you can also double click view to open the editor - + Make copy of the current Organizer - + &Delete - + Delete Organizer without undo - - + + Move Notebook/Note to &Previous Column/Quadrant Ctrl+Left - + Move Notebook/Note to previous column or quadrant... - - + + Move Notebook/Note to Ne&xt Column/Quadrant Ctrl+Right - + Move Notebook/Note to next column or quadrant... - + Note&book - + E&xamine - + Turn Notebook to deck of flashcard and start active recall testing... - + E&xternal Editor Edit Ctrl+X - + Edit current Note in an external editor - use Preferences to configure the editor - + &Forget Ctrl+D - + Save and Leave Ctrl+L - + Move to F&irst Ctrl+Shift+Up - + Move the Note to be the first child of its parent - + Move &Up Ctrl+Up - + Move the Note up - + Move the Note down - + Move to &Last Ctrl+Shift+Down - + Move the Note to be the last child of its parent - + Move to Notebook Ctrl+R - + &Move to Notebook - + Move the current Note to another Notebook... - + &Find Ctrl+Shift+F - + &Undo Ctrl+Z - + Undo - + &Redo Ctrl+Shift+Z - + Redo - + Cu&t Ctrl+X - + Cut - + &Copy Ctrl+C - + Copy - + &Paste Ctrl+V - + Paste - + Swap Nam&e/Description Focus - + Run an external tool to find, explain, process text under the cursor - + Complete Link Ctrl+L - + Spell check Notebook or Note description - + With&out tags - + Insert Notebook's table of contents without tags - + &With tags - + Insert Notebook's table of contents with tags - + Math cheatsheet - + Open MathJax quick reference - + Math live preview - + Open MathJax live demo - + Mermaid dia&grams documentation - + Open Mermaid diagrams documentation - - - - + + + + &Edit - + &Bold - + Format text as bold - + &Italic - + Format text as italic - + &Code - + Format text as inlined source code - + &Strikethrough - + Format text as strikethrough - + &Keyboard - + Format text as keyboard input - + Format block as bulleted list - + Format block as numbered list - - + + Format block as task list - + Format text block as source code - + Block &Quote - + Format text block as blockquote - + Timestam&p - + &Link - + Insert link to a document, image or file - + Insert image - + Tabl&es - + &Horizontal ruler - + Horizontal ruler - + &Format &Formát - + Create new Notebook to form new ideas, principles, combinations or applications - + Edit current Notebook - you can also double click view to open the editor - + Import - - + + Copy the current Notebook as to Stencil - + Make copy of the current Notebook - + Forget Notebook and move it to Limbo - + &Forget Del - + Forget Note - + Make a copy of the Note to this or other Notebook... - + Make &Home @@ -1757,153 +1892,153 @@ Choose new library source: - + S&cope - + Retain - + Recall Note&book by Name - + Recall Library &Doc by Name - + Find Document by name - + Open Home Notebook... - + Show list of Notebooks... - + Note&books Tree - + Show tree of Notebooks... - + &Tags - + Open Tag cloud... - + Knowledge Graph &Navigator - + Open knowledge graph Navigator... - + Open memory dwell... - + View recently modified Notes... - + List Notebook and Note stencils... - + List forgotten Notebooks and Notes... - + D&istraction Free - + Toggle fullscreen - + &New library - + Add path to the directory with documents (PDF, txt, HTML)... - + &Update library - + Synchronize library source directory with MindForger notebook(s) which representlibrary resources... - + &Delete library - + Delete all Notebooks representing the library resources... - + Toggle tag indicating whether to use the current Notebook as home - - + + Make &Stencil - + C&lone - + E&xport E&xport - + &Import @@ -1923,188 +2058,188 @@ Choose new library source: - + A&dapt - + &CSV - + Export all Notebooks/Markdown files as a single CSV file - + Recall Notebook by Ta&gs - + &Home Notebook - + Activate command line interface... - + Str&etch edges e | mouse wheel - + Stretch knowledge graph edges - + &Sh&rink edge E | mouse wheel - + Shring knowledge graph edges - + Zoom &in z - + Zoom in knowledge graph - + Zoom &out Z - + Zoom out knowledge graph - + &Shuffle Space - + Shuffle knowledge graph - + &HTML - + Export Notebook to a file in HTML format - + &TWiki - + Import Notebook from an external TWiki file and restart MindForger - + Create new Note to form new ideas, principles, combinations and applications - + Hoist/de-hoist Note to focus on Note being viewed or edited - + &Edit Ctrl+E - + Edit current Note - you can also double click view to open the editor - + Remember Ctrl+S - + Save Note being edited - + Leave Alt+Left - + Save leave editor of Note being changed - + &Promote Ctrl+Left - + Promote Note - + &Demote Ctrl+Right - + Demote Note - + &Live Preview - + Toggle live HTML preview - + E&xtract - + Create new Note from the text selected in the current Note... - - + + &Clone @@ -2145,666 +2280,683 @@ Choose new library source: - + &Wingman - + Ter&minal - + Run simple command line from current MindForger workspace... - + Emo&jis - + Open dialog with emoji characters to be copy/pasted to names, descriptions and text... - + N&avigate - + Li&brary - + &Edit ⌘↩ - + &Edit Alt-Enter - + Move Notebook/Note to Previous Column/Quadrant ⌘[ - + Move Notebook/Note to Next Column/Quadrant ⌘] - + Focus to Previous Column/Quadrant ⇧⇥ - + Focus to Next Column/Quadrant ⇥ - + &Promote - + Promote Notebook - + De&mote - + Demote Notebook - + Move to &First - + Move the Notebook to be the first child of its parent - + Move &Up - + Move the Notebook up - + Move the Notebook down - + Move to &Last - + Move the Notebook to be the last child of its parent - + Export Note to an external file in a supported format - + Import Note from an external file in a supported format - + &Note - - - - - &Wingman GPT + + Use Wingman LLM to search for similar Notes (associations) using text embeddings... - + Open Wingman dialog... - + &Find on Web - + Find Notebook or Note name; selected text or text under cursor on the web... - + + &Find orphans + + + + + Find library Notebooks which reference non-existent documents... + + + + + Deprecate &orphans + + + + + Deprecate library Notebooks that has tag which indicates reference of non-existent document... + + + + Move focus to previous column or quadrant... - + Move focus to next column or quadrant... - + Move D&own - - + + &Summarize - + Ask Wingman to summarize text of the Notebook... - - + + &Explain - + Ask Wingman to explain the name of the Notebook... - + &Find Tasks - + Ask Wingman to find tasks in the Notebook text... - - - + + + &More prompts... - - - + + + Open Wingman chat... - + Move Dow&n Ctrl+Down - + Ask Wingman to summarize text of the Note... - + &Find Grammar Errors - + Ask Wingman to find grammar errors in the Note text... - + &Translate to English - + Ask Wingman to translate the Note text to English... - + Search Note text - + Find Next Ctrl+F - + Search Note text again - + W&ord Wrap - + Toggle word wrap mode - + Swap focus of N title and description editors - + Complete word being written by finding link to Notebook or Note - + &Spell Check - + &Fix Grammar - + Ask Wingman to fix grammar errors in the selected text / word under the cursor... - + Ask Wingman to explain the word under the cursor / selected text... - + Finish &Text - + Ask Wingman to finish the text following the selected text / word under the cursor... - + &Rewrite Text - + Ask Wingman to rewrite the text following the selected text / word under the cursor... - + &Math - + Format text as math (MathJax) - + Comment - + Add comment to hide text in rendered HTML - + Lis&ts - + &Bulleted List - + &Numbered List - + &Task List - + Task List &Item - + Bl&ocks - + &Code Block - + &Math Block - + &Diagram Block - + Format code block as diagram (Mermaid) - + Diagrams - + &Flowchart - + Insert flowchart Mermaid diagram skeleton - + &Sequence Diagram - + Insert sequence Mermaid diagram skeleton - + &Class Diagram - + Insert class Mermaid diagram skeleton - + St&ate Diagram - + Insert state Mermaid diagram skeleton - + &Gantt Diagram - + Insert Gantt Mermaid diagram skeleton - + &Pie Diagram - + Insert pie Mermaid chart skeleton - + MathJa&x - + &text - + &fraction - + &sum - + s&quare root - + &integral - + &alpha - + &beta - + &Gama - + &Delta - + &bar - + &hat - + &overrightarrow - + &cup - + &empty set - + &not in - + T&able of Contents - + Insert current date and time - + About &Qt - + Format text block as math (MathJax) - + in&tegrals - + dot - + ca&p - + in - + Ima&ge - + Insert table... - + &Documentation - + Open MindForger documentation - + &Web - + Open MindForger web - + &Markdown tutorial - + Open Markdown tutorial - + Report &Bug or Request Feature - + Report bug or suggest an enhancement - + &Check for Updates - + Check for MindForger updates - + About Qt... - + &About MindForger - + About MindForger... O aplikaci MindForger - + &Help - + F1 @@ -2908,13 +3060,13 @@ Choose new library source: - - + + New Note - + Failed to create new Note! @@ -2945,8 +3097,8 @@ Choose new library source: - - + + Specified file path already exists! @@ -2969,7 +3121,7 @@ Choose new library source: - + Notebook @@ -3005,180 +3157,165 @@ Choose new library source: - - Wingman is talking to the GPT provider... - - - - - Wingman received an answer from the GPT provider - - - - - Wingman failed to receive an answer from the GPT provider - - - - - + + Wingman Action Error - + Wingman's answer appended after selected text in the Note editor. - + Unable to append after selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to append after selected text - run a prompt. - + Wingman's answer replaced selected text in Notebook header. - + Unable to replace Notebook header text - no text selected. - + Wingman's answer replaced selected text in Note text. - + Unable to replace Note text - no text selected. - + Unable to replace selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to replace selected text - run a prompt. - + Edit Notebook - + Please open an Notebook to edit. - - + + Clone Notebook - + Failed to clone Notebook! - + Please open and Notebook to be cloned. - + Notebook '%1' successfully marked as home - + Make Notebook home - + Notebook can be marked as home only when viewed. - + Library already indexed - use 'Update library' action to synchronize documents. - + Unable to index documents on library path - either memory directory doesn't exist or not in MindForger workspace mode. - + Library synchronization - + There are no libraries - nothing to synchronize. - + Library deletion - + There are no libraries - nothing to delete. - + Delete Library - + Do you really want to delete Notebooks which represent the library documents? - + Do you really want to forget ' - + ' Notebook? - + Notebook can be forgotten only when viewed. - + Open and view a Notebook to create new Note. - + Edit Note - - + + Please select a Note to edit in the Notebook. @@ -3286,300 +3423,343 @@ Choose new library source: - + + Wingman is runnning inferences... + + + + + Wingman received an answer from the LLM provider + + + + + Wingman failed to receive an answer from the LLM provider + + + + Wingman's answer appended after selected text in the Notebook header. - + Wingman's answer appended after the cursor in the Notebook header. - + Wingman's answer appended after the cursor in the Note editor. - + 🔒 Notebook Write Error - + Notebook file is read-only and cannot be written: '%1' - + Home tag toggled/removed - Notebook '%1' is no longer home - - + + Forget Notebook - + Do you really want to deprecate ' - - - + + + Export Error - + Unable to find Notebook to export! - + Import TWiki File - - + + Edit Note with External Editor Error - + External editor command is not configured in preferences (Editor tab). - - + + Edit Note with External Editor - + Running command: '%1' - + Running command: '%1'. Close external editor to return control back to MindForger. - + Delete Note - + Do you really want to delete note ' - + ' along with its child notes? - + Forget Note - + Please select a Note to forget. - - - + + + Extract Note - + Please select a text to extract. - + Failed to extract new Note! - + Please select a Note, edit it and select a text to extract. - - - + + + Clone Note - + Do you want to clone Note ' - + ' including its child notes?'? - + Failed to clone Note! - + Please select a Note to be cloned. - + Moved Note '%1' to be the first child - - - - + + + + Move Note - - - - + + + + Please select a Note to be moved. - + Moved up Note '%1' - + Moved down Note '%1' - + Moved Note '%1' to be the last child - + Promoted Note '%1' - + Promote Note - + Please select a Note to be promoted. - + Demoted Note '%1' - + Demote Note - + Please select a Note to be demoted. - - - + + + Add Library Error - + Library directory doesn't exist! - + + + + + Library Orphans + + + + + Found %1 library Notebooks with orphaned documents. Notebooks were tagged with 'library-orphan-document' tag. Use scopes to filter them out. + + + + + No Notebooks with orphaned documents found. + + + + + %1 Notebooks tagged as library orphans were deprecated. + + + + + No Notebooks with library orphan tag found. + + + + Organizer Update Error - + Eisenhower Matrix organizer is built-in and cannot be edited - please create or update a custom organizer. - + Organizer Clone Error - + Eisenhower Matrix organizer is built-in and cannot be cloned - please create or update a custom organizer. - + Forget Organizer - + ' Organizer? - + Delete Organizer - + Eisenhower Matrix is built-in and cannot be deleted - only custom organizers can. - + View Limbo - + Limbo directory with deleted Notebooks is available in the MindForger workspace, not if a Markdown is edited or a directory with markdowns is opened. - + Emojis - + About MindForger @@ -3587,7 +3767,7 @@ Choose new library source: m8r::MainWindowView - + Thinking Notebook diff --git a/app/resources/qt/translations/mindforger_nerd_en.qm b/app/resources/qt/translations/mindforger_nerd_en.qm index 1ceeea89..a74771c2 100644 Binary files a/app/resources/qt/translations/mindforger_nerd_en.qm and b/app/resources/qt/translations/mindforger_nerd_en.qm differ diff --git a/app/resources/qt/translations/mindforger_nerd_en.ts b/app/resources/qt/translations/mindforger_nerd_en.ts index a3636fd8..af240b03 100644 --- a/app/resources/qt/translations/mindforger_nerd_en.ts +++ b/app/resources/qt/translations/mindforger_nerd_en.ts @@ -308,52 +308,52 @@ Choose new library source: m8r::ConfigurationDialog::AppTab - + UI theme (<font color='#ff0000'>requires restart</font>) - + Menu (<font color='#ff0000'>requires restart</font>) - + Show the following view on application start - + Application font size - 0 is system (<font color='#ff0000'>requires restart</font>) - + show toolbar - + I don't need buttons - I know all keyboard shortcuts! - + nerd terminology - - Appearance (<font color='#ff0000'>requires restart</font>) + + Appearance - + Controls - + Startup @@ -361,47 +361,47 @@ Choose new library source: m8r::ConfigurationDialog::EditorTab - + Editor key binding - + Editor font - + Spell check dictionaries <a href='https://github.com/dvorka/mindforger/wiki/Installation#spell-check'>configuration documentation</a> - + live spell check - + TABs as SPACEs - + autosave Note on editor close - + TAB width - + External editor command - + Editor @@ -409,37 +409,37 @@ Choose new library source: m8r::ConfigurationDialog::MarkdownTab - + syntax highlighting - + autocomplete text - + autocomplete lists, blocks and {([`_ characters - + SPACE-based # in section escaping (HTML otherwise) - + Rendering - + Autocompletion - + Escaping @@ -447,22 +447,22 @@ Choose new library source: m8r::ConfigurationDialog::MindTab - + save reads metadata - + Async refresh interval (1 - 10.000ms) - + Persistence - + Notifications @@ -470,12 +470,12 @@ Choose new library source: m8r::ConfigurationDialog::NavigatorTab - + Max graph nodes (150 by default) - + Knowledge Graph Navigator @@ -483,101 +483,223 @@ Choose new library source: m8r::ConfigurationDialog::ViewerTab - + HTML Viewer - + Viewer theme CSS - + HTML zoom (100 is 100%, Ctrl + mouse wheel) - + source code syntax highlighting support - + math support - + whole notebook preview - + double click HTML preview to edit - + Diagram support - + Find Custom CSS File - + HTML Viewer CSS - + Choose CSS File - m8r::ConfigurationDialog::WingmanTab + m8r::ConfigurationDialog::WingmanOllamaTab - - LLM provider: + + <html><a href='https://ollama.com'>ollama</a> LLM provider configuration: +<ul><li>Set your ollama server URL - default is <a href='http://localhost:11434'>http://localhost:11434</a></li></ul> + + + + + <br>ollama server URL: + + + + + Set ollama as LLM Provider + + + + + Add ollama to the dropdown with LLM providers (if not there) and set it for use with Wingman + + + + + Refresh LLM models + + + + + Clear URL + + + + + LLM model: + + + + + LLM Provider Config Error + + + + + Unable to set ollama as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + + ollama Server URL Cleared + + + + + ollama server URL has been cleared from the configuration and ollama is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanOpenAiTab + + + <br>API key: + + + + + Refresh LLM models - - <html>Configure <a href='https://openai.com'>OpenAI</a> LLM provider: -<ul><li><a href='https://platform.openai.com/api-keys'>Generate</a> an OpenAI API key.</li><li>Set the API key:<br>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home dir.</li><li><font color='#ff0000'>Restart</font> MindForger to apply the change.</li></ul> + + Set OpenAI as LLM Provider - - Clear OpenAI API Key + + Add OpenAI to the dropdown with LLM providers (if not there) and set it for use with Wingman - + + Clear API Key + + + + + LLM model: + + + + + The OpenAI API key is configured using the environment<br/>variable <b>%1</b>.<br/>If you want to override it, then set the key below.<br/>It will be saved <font color='#ff0000'>unencrypted</font> to <b>.mindforger.md</b> configuration file in your home directory. + + + + + <html><a href='https://openai.com'>OpenAI</a> LLM provider configuration: +<ul><li>Generate new OpenAI API key at <a href='https://platform.openai.com/api-keys'>openai.com</a>.</li><li>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home directory.</li></ul> + + + + + The OpenAI API key is configured both using the environment<br/>variable <b>%1</b> and configuration.<br/>Configuration overrides environment - key from below is used. + + + + + The OpenAI API key is configured using the key below. + + + + + LLM Provider Config Error + + + + + Unable to set OpenAI as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + OpenAI API Key Cleared - - API key has been cleared from the configuration. Please close the configuration dialog with the OK button and restart MindForger to apply this change. + + API key has been cleared from the configuration and OpenAI is no longer the LLM provider. + + + m8r::ConfigurationDialog::WingmanTab - - Data Privacy Warning + + LLM provider: - - You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers for GPT processing when you use Wingman. + + OpenAI + + + + + ollama + + + + + You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers when you use Wingman. + + + + + Data Privacy Warning - + Large language model (LLM) providers @@ -1074,10 +1196,10 @@ Choose new library source: - - - - + + + + &New @@ -1092,7 +1214,7 @@ Choose new library source: - + &Recall @@ -1103,7 +1225,7 @@ Choose new library source: - + &Forget @@ -1113,17 +1235,17 @@ Choose new library source: - + Adapt Mind by setting your preferences... - + E&xit - + Leave application @@ -1133,589 +1255,602 @@ Choose new library source: &Mind - + &Full-text Search - + Note full-text search - + Recall &Note by Name - + Find Note by name - + Find Note by tags - + &Memory Dwell - + &Recent Notes - + &Stencils - + Don't show Notebooks and Notes older than... - + + &Semantic Search + + + + + + + + &Wingman LLM + + + + Create backup archive of the current workspace and store it in home directory - + Find Notebook by name - + Find Notebook by tags - + Recall Note by T&ags - + Flashcard &Decks - + Show list of flashcard decks... - + Organiz&ers - + Open Eisenhower matrix and Kanban organizers... - + N&otebooks - + &Library Documents - + List Library documents... - + &CLI - + Li&mbo - + Ho&ist - + Toggle distraction free mode - + &Fullscreen - + &View - + Str&etch edges - + &Sh&rink edge - + Flash&cards - + &Organizer - + Create new Organizer to prioritize your knowledge in Eisenhower Matrix style - + Edit current Organizer - you can also double click view to open the editor - + Make copy of the current Organizer - + &Delete - + Delete Organizer without undo - - + + Move Notebook/Note to &Previous Column/Quadrant Ctrl+Left - + Move Notebook/Note to previous column or quadrant... - - + + Move Notebook/Note to Ne&xt Column/Quadrant Ctrl+Right - + Move Notebook/Note to next column or quadrant... - + Note&book - + E&xamine - + Turn Notebook to deck of flashcard and start active recall testing... - + E&xternal Editor Edit Ctrl+X - + Edit current Note in an external editor - use Preferences to configure the editor - + &Forget Ctrl+D - + Save and Leave Ctrl+L - + Move to F&irst Ctrl+Shift+Up - + Move the Note to be the first child of its parent - + Move &Up Ctrl+Up - + Move the Note up - + Move the Note down - + Move to &Last Ctrl+Shift+Down - + Move the Note to be the last child of its parent - + Move to Notebook Ctrl+R - + &Move to Notebook - + Move the current Note to another Notebook... - + &Find Ctrl+Shift+F - + &Undo Ctrl+Z - + Undo - + &Redo Ctrl+Shift+Z - + Redo - + Cu&t Ctrl+X - + Cut - + &Copy Ctrl+C - + Copy - + &Paste Ctrl+V - + Paste - + Swap Nam&e/Description Focus - + Run an external tool to find, explain, process text under the cursor - + Complete Link Ctrl+L - + Spell check Notebook or Note description - + With&out tags - + Insert Notebook's table of contents without tags - + &With tags - + Insert Notebook's table of contents with tags - + Math cheatsheet - + Open MathJax quick reference - + Math live preview - + Open MathJax live demo - + Mermaid dia&grams documentation - + Open Mermaid diagrams documentation - - - - + + + + &Edit - + &Bold - + Format text as bold - + &Italic - + Format text as italic - + &Code - + Format text as inlined source code - + &Strikethrough - + Format text as strikethrough - + &Keyboard - + Format text as keyboard input - + Format block as bulleted list - + Format block as numbered list - - + + Format block as task list - + Format text block as source code - + Block &Quote - + Format text block as blockquote - + Timestam&p - + &Link - + Insert link to a document, image or file - + Insert image - + Tabl&es - + &Horizontal ruler - + Horizontal ruler - + &Format - + Create new Notebook to form new ideas, principles, combinations or applications - + Edit current Notebook - you can also double click view to open the editor - + Import - - + + Copy the current Notebook as to Stencil - + Make copy of the current Notebook - + Forget Notebook and move it to Limbo - + &Forget Del - + Forget Note - + Make a copy of the Note to this or other Notebook... - + Make &Home @@ -1741,153 +1876,153 @@ Choose new library source: - + S&cope - + Retain - + Recall Note&book by Name - + Recall Library &Doc by Name - + Find Document by name - + Open Home Notebook... - + Show list of Notebooks... - + Note&books Tree - + Show tree of Notebooks... - + &Tags - + Open Tag cloud... - + Knowledge Graph &Navigator - + Open knowledge graph Navigator... - + Open memory dwell... - + View recently modified Notes... - + List Notebook and Note stencils... - + List forgotten Notebooks and Notes... - + D&istraction Free - + Toggle fullscreen - + &New library - + Add path to the directory with documents (PDF, txt, HTML)... - + &Update library - + Synchronize library source directory with MindForger notebook(s) which representlibrary resources... - + &Delete library - + Delete all Notebooks representing the library resources... - + Toggle tag indicating whether to use the current Notebook as home - - + + Make &Stencil - + C&lone - + E&xport - + &Import @@ -1907,188 +2042,188 @@ Choose new library source: - + A&dapt - + &CSV - + Export all Notebooks/Markdown files as a single CSV file - + Recall Notebook by Ta&gs - + &Home Notebook - + Activate command line interface... - + Str&etch edges e | mouse wheel - + Stretch knowledge graph edges - + &Sh&rink edge E | mouse wheel - + Shring knowledge graph edges - + Zoom &in z - + Zoom in knowledge graph - + Zoom &out Z - + Zoom out knowledge graph - + &Shuffle Space - + Shuffle knowledge graph - + &HTML - + Export Notebook to a file in HTML format - + &TWiki - + Import Notebook from an external TWiki file and restart MindForger - + Create new Note to form new ideas, principles, combinations and applications - + Hoist/de-hoist Note to focus on Note being viewed or edited - + &Edit Ctrl+E - + Edit current Note - you can also double click view to open the editor - + Remember Ctrl+S - + Save Note being edited - + Leave Alt+Left - + Save leave editor of Note being changed - + &Promote Ctrl+Left - + Promote Note - + &Demote Ctrl+Right - + Demote Note - + &Live Preview - + Toggle live HTML preview - + E&xtract - + Create new Note from the text selected in the current Note... - - + + &Clone @@ -2129,666 +2264,683 @@ Choose new library source: - + &Wingman - + Ter&minal - + Run simple command line from current MindForger workspace... - + Emo&jis - + Open dialog with emoji characters to be copy/pasted to names, descriptions and text... - + N&avigate - + Li&brary - + &Edit ⌘↩ - + &Edit Alt-Enter - + Move Notebook/Note to Previous Column/Quadrant ⌘[ - + Move Notebook/Note to Next Column/Quadrant ⌘] - + Focus to Previous Column/Quadrant ⇧⇥ - + Focus to Next Column/Quadrant ⇥ - + &Promote - + Promote Notebook - + De&mote - + Demote Notebook - + Move to &First - + Move the Notebook to be the first child of its parent - + Move &Up - + Move the Notebook up - + Move the Notebook down - + Move to &Last - + Move the Notebook to be the last child of its parent - + Export Note to an external file in a supported format - + Import Note from an external file in a supported format - + &Note - - - - - &Wingman GPT + + Use Wingman LLM to search for similar Notes (associations) using text embeddings... - + Open Wingman dialog... - + &Find on Web - + Find Notebook or Note name; selected text or text under cursor on the web... - + + &Find orphans + + + + + Find library Notebooks which reference non-existent documents... + + + + + Deprecate &orphans + + + + + Deprecate library Notebooks that has tag which indicates reference of non-existent document... + + + + Move focus to previous column or quadrant... - + Move focus to next column or quadrant... - + Move D&own - - + + &Summarize - + Ask Wingman to summarize text of the Notebook... - - + + &Explain - + Ask Wingman to explain the name of the Notebook... - + &Find Tasks - + Ask Wingman to find tasks in the Notebook text... - - - + + + &More prompts... - - - + + + Open Wingman chat... - + Move Dow&n Ctrl+Down - + Ask Wingman to summarize text of the Note... - + &Find Grammar Errors - + Ask Wingman to find grammar errors in the Note text... - + &Translate to English - + Ask Wingman to translate the Note text to English... - + Search Note text - + Find Next Ctrl+F - + Search Note text again - + W&ord Wrap - + Toggle word wrap mode - + Swap focus of N title and description editors - + Complete word being written by finding link to Notebook or Note - + &Spell Check - + &Fix Grammar - + Ask Wingman to fix grammar errors in the selected text / word under the cursor... - + Ask Wingman to explain the word under the cursor / selected text... - + Finish &Text - + Ask Wingman to finish the text following the selected text / word under the cursor... - + &Rewrite Text - + Ask Wingman to rewrite the text following the selected text / word under the cursor... - + &Math - + Format text as math (MathJax) - + Comment - + Add comment to hide text in rendered HTML - + Lis&ts - + &Bulleted List - + &Numbered List - + &Task List - + Task List &Item - + Bl&ocks - + &Code Block - + &Math Block - + &Diagram Block - + Format code block as diagram (Mermaid) - + Diagrams - + &Flowchart - + Insert flowchart Mermaid diagram skeleton - + &Sequence Diagram - + Insert sequence Mermaid diagram skeleton - + &Class Diagram - + Insert class Mermaid diagram skeleton - + St&ate Diagram - + Insert state Mermaid diagram skeleton - + &Gantt Diagram - + Insert Gantt Mermaid diagram skeleton - + &Pie Diagram - + Insert pie Mermaid chart skeleton - + MathJa&x - + &text - + &fraction - + &sum - + s&quare root - + &integral - + &alpha - + &beta - + &Gama - + &Delta - + &bar - + &hat - + &overrightarrow - + &cup - + &empty set - + &not in - + T&able of Contents - + Insert current date and time - + About &Qt - + Format text block as math (MathJax) - + in&tegrals - + dot - + ca&p - + in - + Ima&ge - + Insert table... - + &Documentation - + F1 - + Open MindForger documentation - + &Web - + Open MindForger web - + &Markdown tutorial - + Open Markdown tutorial - + Report &Bug or Request Feature - + Report bug or suggest an enhancement - + &Check for Updates - + Check for MindForger updates - + About Qt... - + &About MindForger - + About MindForger... - + &Help @@ -2892,13 +3044,13 @@ Choose new library source: - - + + New Note - + Failed to create new Note! @@ -2929,8 +3081,8 @@ Choose new library source: - - + + Specified file path already exists! @@ -2953,7 +3105,7 @@ Choose new library source: - + Notebook @@ -2989,180 +3141,165 @@ Choose new library source: - - Wingman is talking to the GPT provider... - - - - - Wingman received an answer from the GPT provider - - - - - Wingman failed to receive an answer from the GPT provider - - - - - + + Wingman Action Error - + Wingman's answer appended after selected text in the Note editor. - + Unable to append after selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to append after selected text - run a prompt. - + Wingman's answer replaced selected text in Notebook header. - + Unable to replace Notebook header text - no text selected. - + Wingman's answer replaced selected text in Note text. - + Unable to replace Note text - no text selected. - + Unable to replace selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to replace selected text - run a prompt. - + Edit Notebook - + Please open an Notebook to edit. - - + + Clone Notebook - + Failed to clone Notebook! - + Please open and Notebook to be cloned. - + Notebook '%1' successfully marked as home - + Make Notebook home - + Notebook can be marked as home only when viewed. - + Library already indexed - use 'Update library' action to synchronize documents. - + Unable to index documents on library path - either memory directory doesn't exist or not in MindForger workspace mode. - + Library synchronization - + There are no libraries - nothing to synchronize. - + Library deletion - + There are no libraries - nothing to delete. - + Delete Library - + Do you really want to delete Notebooks which represent the library documents? - + Do you really want to forget ' - + ' Notebook? - + Notebook can be forgotten only when viewed. - + Open and view a Notebook to create new Note. - + Edit Note - - + + Please select a Note to edit in the Notebook. @@ -3270,300 +3407,343 @@ Choose new library source: - + + Wingman is runnning inferences... + + + + + Wingman received an answer from the LLM provider + + + + + Wingman failed to receive an answer from the LLM provider + + + + Wingman's answer appended after selected text in the Notebook header. - + Wingman's answer appended after the cursor in the Notebook header. - + Wingman's answer appended after the cursor in the Note editor. - + 🔒 Notebook Write Error - + Notebook file is read-only and cannot be written: '%1' - + Home tag toggled/removed - Notebook '%1' is no longer home - - + + Forget Notebook - + Do you really want to deprecate ' - - - + + + Export Error - + Unable to find Notebook to export! - + Import TWiki File - - + + Edit Note with External Editor Error - + External editor command is not configured in preferences (Editor tab). - - + + Edit Note with External Editor - + Running command: '%1' - + Running command: '%1'. Close external editor to return control back to MindForger. - + Delete Note - + Do you really want to delete note ' - + ' along with its child notes? - + Forget Note - + Please select a Note to forget. - - - + + + Extract Note - + Please select a text to extract. - + Failed to extract new Note! - + Please select a Note, edit it and select a text to extract. - - - + + + Clone Note - + Do you want to clone Note ' - + ' including its child notes?'? - + Failed to clone Note! - + Please select a Note to be cloned. - + Moved Note '%1' to be the first child - - - - + + + + Move Note - - - - + + + + Please select a Note to be moved. - + Moved up Note '%1' - + Moved down Note '%1' - + Moved Note '%1' to be the last child - + Promoted Note '%1' - + Promote Note - + Please select a Note to be promoted. - + Demoted Note '%1' - + Demote Note - + Please select a Note to be demoted. - - - + + + Add Library Error - + Library directory doesn't exist! - + + + + + Library Orphans + + + + + Found %1 library Notebooks with orphaned documents. Notebooks were tagged with 'library-orphan-document' tag. Use scopes to filter them out. + + + + + No Notebooks with orphaned documents found. + + + + + %1 Notebooks tagged as library orphans were deprecated. + + + + + No Notebooks with library orphan tag found. + + + + Organizer Update Error - + Eisenhower Matrix organizer is built-in and cannot be edited - please create or update a custom organizer. - + Organizer Clone Error - + Eisenhower Matrix organizer is built-in and cannot be cloned - please create or update a custom organizer. - + Forget Organizer - + ' Organizer? - + Delete Organizer - + Eisenhower Matrix is built-in and cannot be deleted - only custom organizers can. - + View Limbo - + Limbo directory with deleted Notebooks is available in the MindForger workspace, not if a Markdown is edited or a directory with markdowns is opened. - + Emojis - + About MindForger @@ -3571,7 +3751,7 @@ Choose new library source: m8r::MainWindowView - + Thinking Notebook diff --git a/app/resources/qt/translations/mindforger_zh_cn.qm b/app/resources/qt/translations/mindforger_zh_cn.qm index be8d9143..1ad5d339 100644 Binary files a/app/resources/qt/translations/mindforger_zh_cn.qm and b/app/resources/qt/translations/mindforger_zh_cn.qm differ diff --git a/app/resources/qt/translations/mindforger_zh_cn.ts b/app/resources/qt/translations/mindforger_zh_cn.ts index 92ce3df1..2b043536 100644 --- a/app/resources/qt/translations/mindforger_zh_cn.ts +++ b/app/resources/qt/translations/mindforger_zh_cn.ts @@ -309,52 +309,52 @@ Choose new library source: m8r::ConfigurationDialog::AppTab - + UI theme (<font color='#ff0000'>requires restart</font>) - + Menu (<font color='#ff0000'>requires restart</font>) - + Show the following view on application start - + Application font size - 0 is system (<font color='#ff0000'>requires restart</font>) - + show toolbar - + I don't need buttons - I know all keyboard shortcuts! - + nerd terminology - - Appearance (<font color='#ff0000'>requires restart</font>) + + Appearance - + Controls - + Startup @@ -362,47 +362,47 @@ Choose new library source: m8r::ConfigurationDialog::EditorTab - + Editor key binding - + Editor font - + Spell check dictionaries <a href='https://github.com/dvorka/mindforger/wiki/Installation#spell-check'>configuration documentation</a> - + live spell check - + TABs as SPACEs - + autosave Note on editor close - + TAB width - + External editor command - + Editor @@ -410,37 +410,37 @@ Choose new library source: m8r::ConfigurationDialog::MarkdownTab - + syntax highlighting - + autocomplete text - + autocomplete lists, blocks and {([`_ characters - + SPACE-based # in section escaping (HTML otherwise) - + Rendering - + Autocompletion - + Escaping @@ -448,22 +448,22 @@ Choose new library source: m8r::ConfigurationDialog::MindTab - + save reads metadata - + Async refresh interval (1 - 10.000ms) - + Persistence - + Notifications @@ -471,12 +471,12 @@ Choose new library source: m8r::ConfigurationDialog::NavigatorTab - + Max graph nodes (150 by default) - + Knowledge Graph Navigator @@ -484,101 +484,223 @@ Choose new library source: m8r::ConfigurationDialog::ViewerTab - + HTML Viewer - + Viewer theme CSS - + HTML zoom (100 is 100%, Ctrl + mouse wheel) - + source code syntax highlighting support - + math support - + whole notebook preview - + double click HTML preview to edit - + Diagram support - + Find Custom CSS File - + HTML Viewer CSS - + Choose CSS File - m8r::ConfigurationDialog::WingmanTab + m8r::ConfigurationDialog::WingmanOllamaTab - - LLM provider: + + <html><a href='https://ollama.com'>ollama</a> LLM provider configuration: +<ul><li>Set your ollama server URL - default is <a href='http://localhost:11434'>http://localhost:11434</a></li></ul> + + + + + <br>ollama server URL: + + + + + Set ollama as LLM Provider + + + + + Add ollama to the dropdown with LLM providers (if not there) and set it for use with Wingman + + + + + Refresh LLM models + + + + + Clear URL + + + + + LLM model: + + + + + LLM Provider Config Error + + + + + Unable to set ollama as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + + ollama Server URL Cleared + + + + + ollama server URL has been cleared from the configuration and ollama is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanOpenAiTab + + + <br>API key: + + + + + Refresh LLM models - - <html>Configure <a href='https://openai.com'>OpenAI</a> LLM provider: -<ul><li><a href='https://platform.openai.com/api-keys'>Generate</a> an OpenAI API key.</li><li>Set the API key:<br>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home dir.</li><li><font color='#ff0000'>Restart</font> MindForger to apply the change.</li></ul> + + Set OpenAI as LLM Provider - - Clear OpenAI API Key + + Add OpenAI to the dropdown with LLM providers (if not there) and set it for use with Wingman - + + Clear API Key + + + + + LLM model: + + + + + The OpenAI API key is configured using the environment<br/>variable <b>%1</b>.<br/>If you want to override it, then set the key below.<br/>It will be saved <font color='#ff0000'>unencrypted</font> to <b>.mindforger.md</b> configuration file in your home directory. + + + + + <html><a href='https://openai.com'>OpenAI</a> LLM provider configuration: +<ul><li>Generate new OpenAI API key at <a href='https://platform.openai.com/api-keys'>openai.com</a>.</li><li>a) either set the <b>%1</b> environment variable<br/>with the API key<br/>b) or paste the API key below to save it <font color='#ff0000'>unencrypted</font> to<br/><b>.mindforger.md</b> file in your home directory.</li></ul> + + + + + The OpenAI API key is configured both using the environment<br/>variable <b>%1</b> and configuration.<br/>Configuration overrides environment - key from below is used. + + + + + The OpenAI API key is configured using the key below. + + + + + LLM Provider Config Error + + + + + Unable to set OpenAI as LLM provider as neither API key is set in the configuration, nor it is defined and environment variable + + + + OpenAI API Key Cleared - - API key has been cleared from the configuration. Please close the configuration dialog with the OK button and restart MindForger to apply this change. + + API key has been cleared from the configuration and OpenAI is no longer the LLM provider. + + + + + m8r::ConfigurationDialog::WingmanTab + + + LLM provider: - - Data Privacy Warning + + OpenAI - - You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers for GPT processing when you use Wingman. + + ollama + + + + + You have chosen OpenAI as your Wingman LLM provider. Therefore, your data will be sent to OpenAI servers when you use Wingman. + + + + + Data Privacy Warning - + Large language model (LLM) providers @@ -1130,18 +1252,18 @@ Choose new library source: - + S&cope - + Don't show Notebooks and Notes older than... - + &Forget &Deprecate @@ -1151,7 +1273,7 @@ Choose new library source: - + Retain Reta&in @@ -1160,47 +1282,47 @@ Choose new library source: &Preferences - + Adapt Mind by setting your preferences... - + E&xit - + Leave application - + &Full-text Search - + Note full-text search - + Recall Note&book by Name Find Note&book by Name - + Find Notebook by name - + Recall &Note by Name Find &Note by Name - + Find Note by name @@ -1209,7 +1331,7 @@ Choose new library source: Find Notebook by T&ags - + Find Notebook by tags @@ -1218,17 +1340,17 @@ Choose new library source: Find Note by &Tags - + Find Note by tags - + Recall Library &Doc by Name - + Find Document by name @@ -1249,1048 +1371,1086 @@ Choose new library source: Find Other Entities - + &Recall F&ind - + Open Home Notebook... - + N&otebooks - + Show list of Notebooks... - + Note&books Tree - + Show tree of Notebooks... - + &Tags - + Open Tag cloud... - + Knowledge Graph &Navigator - + Open knowledge graph Navigator... - + &Memory Dwell - + Open memory dwell... - + Ter&minal - + Run simple command line from current MindForger workspace... - + &Recent Notes - + View recently modified Notes... - + &Stencils - + List Notebook and Note stencils... - + List forgotten Notebooks and Notes... - + D&istraction Free - + Toggle distraction free mode - + &Fullscreen - + Toggle fullscreen - + &View - + Str&etch edges e | mouse wheel - + Stretch knowledge graph edges - + &Sh&rink edge E | mouse wheel - + Shring knowledge graph edges - + Zoom &in z - + Zoom in knowledge graph - + Zoom &out Z - + Zoom out knowledge graph - + &Shuffle Space - + Shuffle knowledge graph - + N&avigate - + &New library - + Add path to the directory with documents (PDF, txt, HTML)... - + &Update library - + Synchronize library source directory with MindForger notebook(s) which representlibrary resources... - + &Delete library - + Delete all Notebooks representing the library resources... - + &Edit ⌘↩ - + &Edit Alt-Enter - + Move Notebook/Note to Previous Column/Quadrant ⌘[ - + Move Notebook/Note to Next Column/Quadrant ⌘] - + Focus to Previous Column/Quadrant ⇧⇥ - + Focus to Next Column/Quadrant ⇥ - + &HTML - + Export Notebook to a file in HTML format - + &TWiki - + Import Notebook from an external TWiki file and restart MindForger - + Search Note text - + Find Next Ctrl+F - + Search Note text again - + &Undo Ctrl+Z - + Undo - + &Redo Ctrl+Shift+Z - + Redo - + Cu&t Ctrl+X - + Cut - + &Copy Ctrl+C - + Copy - + &Paste Ctrl+V - + Paste - - - - + + + + &Edit - + Create backup archive of the current workspace and store it in home directory - + Recall Note by T&ags - + Flashcard &Decks - + Show list of flashcard decks... - + Organiz&ers - + Open Eisenhower matrix and Kanban organizers... - + &Library Documents - + List Library documents... - + &Wingman - + Emo&jis - + Open dialog with emoji characters to be copy/pasted to names, descriptions and text... - + Li&mbo - - &Find on Web + + &Semantic Search + + + + + Use Wingman LLM to search for similar Notes (associations) using text embeddings... + + + + &Wingman LLM + + + + + &Find on Web + + + + Find Notebook or Note name; selected text or text under cursor on the web... - + Li&brary - + + &Find orphans + + + + + Find library Notebooks which reference non-existent documents... + + + + + Deprecate &orphans + + + + + Deprecate library Notebooks that has tag which indicates reference of non-existent document... + + + + &CLI - + Ho&ist - + Str&etch edges - + &Sh&rink edge - + Flash&cards - + &Organizer - + Create new Organizer to prioritize your knowledge in Eisenhower Matrix style - + Edit current Organizer - you can also double click view to open the editor - + Make copy of the current Organizer - + &Delete - + Delete Organizer without undo - - + + Move Notebook/Note to &Previous Column/Quadrant Ctrl+Left - + Move Notebook/Note to previous column or quadrant... - - + + Move Notebook/Note to Ne&xt Column/Quadrant Ctrl+Right - + Move Notebook/Note to next column or quadrant... - + Note&book - + E&xamine - + Turn Notebook to deck of flashcard and start active recall testing... - + &Promote - + Promote Notebook - + De&mote - + Demote Notebook - + Move to &First - + Move the Notebook to be the first child of its parent - + Move &Up - + Move the Notebook up - + Move the Notebook down - + Move to &Last - + Move the Notebook to be the last child of its parent - + E&xternal Editor Edit Ctrl+X - + Edit current Note in an external editor - use Preferences to configure the editor - + &Forget Ctrl+D - + Save and Leave Ctrl+L - + Move to F&irst Ctrl+Shift+Up - + Move the Note to be the first child of its parent - + Move &Up Ctrl+Up - + Move the Note up - + Move the Note down - + Move to &Last Ctrl+Shift+Down - + Move the Note to be the last child of its parent - + Move to Notebook Ctrl+R - + &Move to Notebook - + Move the current Note to another Notebook... - + &Find Ctrl+Shift+F - + &Live Preview - + Toggle live HTML preview - + Swap focus of N title and description editors - + Run an external tool to find, explain, process text under the cursor - + Complete Link Ctrl+L - + Spell check Notebook or Note description - + &Bold - + Format text as bold - + &Italic - + Format text as italic - + &Code - + Format text as inlined source code - + &Math - + Format text as math (MathJax) - + Comment - + Add comment to hide text in rendered HTML - + Lis&ts - + &Bulleted List - + &Numbered List - + &Task List - + Task List &Item - + Bl&ocks - + &Code Block - + &Math Block - + &Diagram Block - + Format code block as diagram (Mermaid) - + Diagrams - + &Flowchart - + Insert flowchart Mermaid diagram skeleton - + &Sequence Diagram - + Insert sequence Mermaid diagram skeleton - + &Class Diagram - + Insert class Mermaid diagram skeleton - + St&ate Diagram - + Insert state Mermaid diagram skeleton - + &Gantt Diagram - + Insert Gantt Mermaid diagram skeleton - + &Pie Diagram - + Insert pie Mermaid chart skeleton - + in&tegrals - + dot - + ca&p - + in - + &Strikethrough - + Format text as strikethrough - + About &Qt - + &Keyboard - + Format text as keyboard input - + Math cheatsheet - + Open MathJax quick reference - + Math live preview - + Open MathJax live demo - + Mermaid dia&grams documentation - + Open Mermaid diagrams documentation - + Format block as bulleted list - + Format block as numbered list - - + + Format block as task list - + T&able of Contents - + Insert current date and time - + Format text block as source code - + Format text block as math (MathJax) - + Block &Quote - + Format text block as blockquote - + &Link - + Insert link to a document, image or file - + Insert image - + Tabl&es - + &Horizontal ruler - + Horizontal ruler - + &Format - - - - + + + + &New - + Create new Notebook to form new ideas, principles, combinations or applications - + Edit current Notebook - you can also double click view to open the editor - + Make &Home - + Import - - + + Make &Stencil - - + + Copy the current Notebook as to Stencil - + C&lone - + Make copy of the current Notebook - + Forget Notebook and move it to Limbo Delete Notebook and move it Limbo - + E&xport - + &Forget Del Delete Del - + Forget Note Delete Note @@ -2300,12 +2460,12 @@ Choose new library source: &Open - + Toggle tag indicating whether to use the current Notebook as home - + &Import @@ -2325,108 +2485,108 @@ Choose new library source: - + A&dapt &Preferences - + &CSV - + Export all Notebooks/Markdown files as a single CSV file - + Recall Notebook by Ta&gs Find Notebook by Ta&gs - + &Home Notebook - + Activate command line interface... - + Create new Note to form new ideas, principles, combinations and applications - + Hoist/de-hoist Note to focus on Note being viewed or edited - + &Edit Ctrl+E - + Edit current Note - you can also double click view to open the editor - + Remember Ctrl+S Save Ctrl+S - + Save Note being edited - + Leave Alt+Left - + Save leave editor of Note being changed - + &Promote Ctrl+Left - + Promote Note - + &Demote Ctrl+Right - + Demote Note - + E&xtract - + Create new Note from the text selected in the current Note... - - + + &Clone @@ -2467,376 +2627,368 @@ Choose new library source: - + Make a copy of the Note to this or other Notebook... - + Export Note to an external file in a supported format - + Import Note from an external file in a supported format - + &Note - - - - - &Wingman GPT - - - - + Open Wingman dialog... - + Move focus to previous column or quadrant... - + Move focus to next column or quadrant... - + Move D&own - - + + &Summarize - + Ask Wingman to summarize text of the Notebook... - - + + &Explain - + Ask Wingman to explain the name of the Notebook... - + &Find Tasks - + Ask Wingman to find tasks in the Notebook text... - - - + + + &More prompts... - - - + + + Open Wingman chat... - + Move Dow&n Ctrl+Down - + Ask Wingman to summarize text of the Note... - + &Find Grammar Errors - + Ask Wingman to find grammar errors in the Note text... - + &Translate to English - + Ask Wingman to translate the Note text to English... - + W&ord Wrap - + Toggle word wrap mode - + Swap Nam&e/Description Focus - + Complete word being written by finding link to Notebook or Note - + &Spell Check - + &Fix Grammar - + Ask Wingman to fix grammar errors in the selected text / word under the cursor... - + Ask Wingman to explain the word under the cursor / selected text... - + Finish &Text - + Ask Wingman to finish the text following the selected text / word under the cursor... - + &Rewrite Text - + Ask Wingman to rewrite the text following the selected text / word under the cursor... - + MathJa&x - + &text - + &fraction - + &sum - + s&quare root - + &integral - + &alpha - + &beta - + &Gama - + &Delta - + &bar - + &hat - + &overrightarrow - + &cup - + &empty set - + &not in - + With&out tags - + Insert Notebook's table of contents without tags - + &With tags - + Insert Notebook's table of contents with tags - + Timestam&p - + Ima&ge - + Insert table... - + &Documentation - + F1 - + Open MindForger documentation - + &Web - + Open MindForger web - + &Markdown tutorial - + Open Markdown tutorial - + Report &Bug or Request Feature - + Report bug or suggest an enhancement - + &Check for Updates - + Check for MindForger updates - + About Qt... - + &About MindForger - + About MindForger... - + &Help @@ -2913,8 +3065,8 @@ Choose new library source: - - + + Specified file path already exists! @@ -2972,7 +3124,7 @@ Choose new library source: - + Notebook @@ -3067,181 +3219,166 @@ Choose new library source: - - Wingman is talking to the GPT provider... - - - - - Wingman received an answer from the GPT provider - - - - - Wingman failed to receive an answer from the GPT provider - - - - - + + Wingman Action Error - + Wingman's answer appended after selected text in the Note editor. - + Unable to append after selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to append after selected text - run a prompt. - + Wingman's answer replaced selected text in Notebook header. - + Unable to replace Notebook header text - no text selected. - + Wingman's answer replaced selected text in Note text. - + Unable to replace Note text - no text selected. - + Unable to replace selected text with Wingman's answer in non-edit perspective. - + No answer from Wingman to replace selected text - run a prompt. - + Edit Notebook - + Please open an Notebook to edit. - - + + New Note - + Failed to create new Note! - - + + Clone Notebook - + Failed to clone Notebook! - + Please open and Notebook to be cloned. - + Home tag toggled/removed - Notebook '%1' is no longer home - + Notebook '%1' successfully marked as home - + Make Notebook home - + Notebook can be marked as home only when viewed. - - + + Forget Notebook Deprecate Notebook - + Library already indexed - use 'Update library' action to synchronize documents. - + Unable to index documents on library path - either memory directory doesn't exist or not in MindForger workspace mode. - + Library synchronization - + There are no libraries - nothing to synchronize. - + Library deletion - + There are no libraries - nothing to delete. - + Delete Library - + Do you really want to delete Notebooks which represent the library documents? - + Do you really want to forget ' - + ' Notebook? @@ -3312,310 +3449,353 @@ Choose new library source: - + + Wingman is runnning inferences... + + + + + Wingman received an answer from the LLM provider + + + + + Wingman failed to receive an answer from the LLM provider + + + + Wingman's answer appended after selected text in the Notebook header. - + Wingman's answer appended after the cursor in the Notebook header. - + Wingman's answer appended after the cursor in the Note editor. - + 🔒 Notebook Write Error - + Notebook file is read-only and cannot be written: '%1' - + Do you really want to deprecate ' - + Notebook can be forgotten only when viewed. - - - + + + Export Error - + Unable to find Notebook to export! - + Import TWiki File - + Open and view a Notebook to create new Note. - + Edit Note - - + + Please select a Note to edit in the Notebook. - - + + Edit Note with External Editor Error - + External editor command is not configured in preferences (Editor tab). - - + + Edit Note with External Editor - + Running command: '%1' - + Running command: '%1'. Close external editor to return control back to MindForger. - + Delete Note - + Do you really want to delete note ' - + ' along with its child notes? - + Forget Note Delete Note - + Please select a Note to forget. Please select a Note to delete. - - - + + + Extract Note - + Please select a text to extract. - + Failed to extract new Note! - + Please select a Note, edit it and select a text to extract. - - - + + + Clone Note - + Do you want to clone Note ' - + ' including its child notes?'? - + Failed to clone Note! - + Please select a Note to be cloned. - + Moved Note '%1' to be the first child - - - - + + + + Move Note - - - - + + + + Please select a Note to be moved. - + Moved up Note '%1' - + Moved down Note '%1' - + Moved Note '%1' to be the last child - + Promoted Note '%1' - + Promote Note - + Please select a Note to be promoted. - + Demoted Note '%1' - + Demote Note - + Please select a Note to be demoted. - - - + + + Add Library Error - + Library directory doesn't exist! - + + + + + Library Orphans + + + + + Found %1 library Notebooks with orphaned documents. Notebooks were tagged with 'library-orphan-document' tag. Use scopes to filter them out. + + + + + No Notebooks with orphaned documents found. + + + + + %1 Notebooks tagged as library orphans were deprecated. + + + + + No Notebooks with library orphan tag found. + + + + Organizer Update Error - + Eisenhower Matrix organizer is built-in and cannot be edited - please create or update a custom organizer. - + Organizer Clone Error - + Eisenhower Matrix organizer is built-in and cannot be cloned - please create or update a custom organizer. - + Forget Organizer - + ' Organizer? - + Delete Organizer - + Eisenhower Matrix is built-in and cannot be deleted - only custom organizers can. - + View Limbo - + Limbo directory with deleted Notebooks is available in the MindForger workspace, not if a Markdown is edited or a directory with markdowns is opened. - + Emojis - + About MindForger @@ -3623,7 +3803,7 @@ Choose new library source: m8r::MainWindowView - + Thinking Notebook diff --git a/app/src/qt/dialogs/configuration_dialog.cpp b/app/src/qt/dialogs/configuration_dialog.cpp index 9bca5ee1..bba0c191 100644 --- a/app/src/qt/dialogs/configuration_dialog.cpp +++ b/app/src/qt/dialogs/configuration_dialog.cpp @@ -685,32 +685,16 @@ ConfigurationDialog::WingmanOpenAiTab::WingmanOpenAiTab(QWidget* parent, QComboB parentLlmProvidersCombo{parentLlmProvidersCombo}, config(Configuration::getInstance()) { - helpLabel = new QLabel( - tr( - "OpenAI LLM provider configuration:\n" - "
    " - "
  • Generate new OpenAI API key at openai.com.
  • " - "
  • a) either set the %1 environment variable
    " - "with the API key
    " - "b) or paste the API key below to save it unencrypted to
    " - ".mindforger.md file in your home directory.
  • " - "
" - ).arg(ENV_VAR_OPENAI_API_KEY)); - BUG: if key in config > it overrides the env var > must be visible - hidden ONLY if env key is set & config key is empty - helpLabel->setVisible(!config.canWingmanOpenAiFromEnv()); apiKeyLabel = new QLabel(tr("
API key:")); - apiKeyLabel->setVisible(helpLabel->isVisible()); apiKeyEdit = new QLineEdit(this); - apiKeyEdit->setVisible(helpLabel->isVisible()); + refreshLlmModelsButton = new QPushButton(tr("Refresh LLM models"), this); + refreshLlmModelsButton->setVisible(false); // enabled on valid config > add ollama to drop down > choose it in drop down setOpenAiButton = new QPushButton(tr("Set OpenAI as LLM Provider"), this); setOpenAiButton->setToolTip( tr("Add OpenAI to the dropdown with LLM providers (if not there) and set it for use with Wingman") ); - setOpenAiButton->setVisible(helpLabel->isVisible()); clearApiKeyButton = new QPushButton(tr("Clear API Key"), this); - clearApiKeyButton->setVisible(helpLabel->isVisible()); // LLM model can be choose at any time when a valid configuration is available llmModelsLabel = new QLabel(tr("LLM model:")); llmModelsCombo = new QComboBox(); @@ -718,15 +702,13 @@ ConfigurationDialog::WingmanOpenAiTab::WingmanOpenAiTab(QWidget* parent, QComboB llmModelsCombo->addItem(LLM_MODEL_GPT35_TURBO); llmModelsCombo->addItem(LLM_MODEL_GPT4); - configuredLabel = new QLabel( - tr("The OpenAI API key is configured using the environment variable."), this); - configuredLabel->setVisible(!helpLabel->isVisible()); + // help text is created using initialized dialog fields + helpLabel = new QLabel(getHelpLabelText(), this); QVBoxLayout* llmProvidersLayout = new QVBoxLayout(); llmProvidersLayout->addWidget(helpLabel); llmProvidersLayout->addWidget(apiKeyLabel); llmProvidersLayout->addWidget(apiKeyEdit); - llmProvidersLayout->addWidget(configuredLabel); llmProvidersLayout->addWidget(llmModelsLabel); llmProvidersLayout->addWidget(llmModelsCombo); QHBoxLayout* buttonsLayout = new QHBoxLayout{}; @@ -751,14 +733,56 @@ ConfigurationDialog::WingmanOpenAiTab::WingmanOpenAiTab(QWidget* parent, QComboB ConfigurationDialog::WingmanOpenAiTab::~WingmanOpenAiTab() { delete helpLabel; - delete configuredLabel; delete apiKeyLabel; delete apiKeyEdit; + delete refreshLlmModelsButton; delete clearApiKeyButton; delete llmModelsLabel; delete llmModelsCombo; } +QString ConfigurationDialog::WingmanOpenAiTab::getHelpLabelText() const +{ + if(apiKeyEdit->text().size()==0) { + if(config.canWingmanOpenAiFromEnv()) { + // key: NOT in config & IN env > ENV used + return tr( + "The OpenAI API key is configured using the environment
" + "variable %1.
" + "If you want to override it, then set the key below.
" + "It will be saved unencrypted to " + ".mindforger.md configuration file in your home directory." + ).arg(ENV_VAR_OPENAI_API_KEY); + } else { + // key: NOT in config & NOT in env > NO key + return tr( + "OpenAI LLM provider configuration:\n" + "
    " + "
  • Generate new OpenAI API key at openai.com.
  • " + "
  • a) either set the %1 environment variable
    " + "with the API key
    " + "b) or paste the API key below to save it unencrypted to
    " + ".mindforger.md file in your home directory.
  • " + "
" + ).arg(ENV_VAR_OPENAI_API_KEY); + } + } else { + if(config.canWingmanOpenAiFromEnv()) { + // key: IN config & IN env > CONFIG used + return tr( + "The OpenAI API key is configured both using the environment
" + "variable %1 and configuration.
" + "Configuration overrides environment - key from below is used." + ).arg(ENV_VAR_OPENAI_API_KEY); + } else { + // key: IN config & NOT env > CONFIG used + return tr( + "The OpenAI API key is configured using the key below." + ).arg(ENV_VAR_OPENAI_API_KEY); + } + } +} + void refreshWingmanLlmProvidersComboBox( QComboBox* parentLlmProvidersCombo, Configuration& config @@ -834,6 +858,8 @@ void ConfigurationDialog::WingmanOpenAiTab::refresh() apiKeyEdit->setText(QString::fromStdString(config.getWingmanOpenAiApiKey())); llmModelsCombo->setCurrentText( QString::fromStdString(config.getWingmanOpenAiLlm())); + + helpLabel->setText(getHelpLabelText()); } void ConfigurationDialog::WingmanOpenAiTab::save() @@ -868,6 +894,7 @@ ConfigurationDialog::WingmanOllamaTab::WingmanOllamaTab(QWidget* parent, QComboB setOllamaButton->setToolTip( tr("Add ollama to the dropdown with LLM providers (if not there) and set it for use with Wingman") ); + refreshLlmModelsButton = new QPushButton(tr("Refresh LLM models"), this); clearUrlButton = new QPushButton(tr("Clear URL"), this); llmModelsLabel = new QLabel(tr("LLM model:")); llmModelsCombo = new QComboBox(); @@ -880,6 +907,7 @@ ConfigurationDialog::WingmanOllamaTab::WingmanOllamaTab(QWidget* parent, QComboB llmProvidersLayout->addWidget(llmModelsLabel); llmProvidersLayout->addWidget(llmModelsCombo); QHBoxLayout* buttonsLayout = new QHBoxLayout{}; + buttonsLayout->addWidget(refreshLlmModelsButton); buttonsLayout->addWidget(setOllamaButton); buttonsLayout->addWidget(clearUrlButton); llmProvidersLayout->addLayout(buttonsLayout); @@ -891,6 +919,9 @@ ConfigurationDialog::WingmanOllamaTab::WingmanOllamaTab(QWidget* parent, QComboB layout->addStretch(); setLayout(layout); + QObject::connect( + refreshLlmModelsButton, SIGNAL(clicked()), + this, SLOT(refreshLlmModelsSlot())); QObject::connect( setOllamaButton, SIGNAL(clicked()), this, SLOT(setOllamaSlot())); @@ -904,11 +935,19 @@ ConfigurationDialog::WingmanOllamaTab::~WingmanOllamaTab() delete helpLabel; delete urlLabel; delete urlEdit; + delete refreshLlmModelsButton; delete clearUrlButton; delete llmModelsLabel; delete llmModelsCombo; } +void ConfigurationDialog::WingmanOllamaTab::refreshLlmModelsSlot() +{ + MF_DEBUG("Signal SLOT: refresh LLM models" << endl); + + // TODO: refresh LLM models - how to call mind cleanly? +} + void ConfigurationDialog::WingmanOllamaTab::setOllamaSlot() { MF_DEBUG("Signal SLOT: set ollama" << endl); diff --git a/app/src/qt/dialogs/configuration_dialog.h b/app/src/qt/dialogs/configuration_dialog.h index 140375e9..94e527ab 100644 --- a/app/src/qt/dialogs/configuration_dialog.h +++ b/app/src/qt/dialogs/configuration_dialog.h @@ -90,9 +90,9 @@ class ConfigurationDialog::WingmanOpenAiTab : public QWidget Configuration& config; QLabel* helpLabel; - QLabel* configuredLabel; QLabel* apiKeyLabel; QLineEdit* apiKeyEdit; + QPushButton* refreshLlmModelsButton; QPushButton* setOpenAiButton; QPushButton* clearApiKeyButton; QLabel* llmModelsLabel; @@ -105,6 +105,10 @@ class ConfigurationDialog::WingmanOpenAiTab : public QWidget void refresh(); void save(); +private: + +QString getHelpLabelText() const; + private slots: void setOpenAiSlot(); void clearApiKeySlot(); @@ -125,6 +129,7 @@ class ConfigurationDialog::WingmanOllamaTab : public QWidget QLabel* helpLabel; QLabel* urlLabel; QLineEdit* urlEdit; + QPushButton* refreshLlmModelsButton; QPushButton* setOllamaButton; QPushButton* clearUrlButton; QLabel* llmModelsLabel; @@ -138,6 +143,7 @@ class ConfigurationDialog::WingmanOllamaTab : public QWidget void save(); private slots: + void refreshLlmModelsSlot(); void setOllamaSlot(); void clearUrlSlot(); }; diff --git a/app/src/qt/main_menu_presenter.cpp b/app/src/qt/main_menu_presenter.cpp index 3d059e5c..27572518 100644 --- a/app/src/qt/main_menu_presenter.cpp +++ b/app/src/qt/main_menu_presenter.cpp @@ -45,6 +45,9 @@ MainMenuPresenter::MainMenuPresenter(MainWindowPresenter* mwp) QObject::connect( view->actionMindAutolink, SIGNAL(triggered()), mwp, SLOT(doActionMindToggleAutolink())); + QObject::connect( + view->actionMindSemanticSearch, SIGNAL(triggered()), + mwp, SLOT(doActionMindToggleSemanticSearch())); QObject::connect( view->actionMindLearnDirectory, SIGNAL(triggered()), mwp, SLOT(doActionMindLearnRepository())); diff --git a/app/src/qt/main_menu_view.cpp b/app/src/qt/main_menu_view.cpp index 3194ad29..c1f717b4 100644 --- a/app/src/qt/main_menu_view.cpp +++ b/app/src/qt/main_menu_view.cpp @@ -109,6 +109,12 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView) actionMindAutolink->setVisible(false); #endif + // if Wingman is not configured and/or capable, then dialog with error message is shown (unable to detect it here) + actionMindSemanticSearch = new QAction(QIcon(":/menu-icons/find.svg"), tr("&Semantic Search"), mainWindow); + actionMindSemanticSearch->setCheckable(true); + actionMindSemanticSearch->setStatusTip(tr("Use Wingman LLM to search for similar Notes (associations) using text embeddings...")); + actionMindSemanticSearch->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_S)); + actionMindWingman = new QAction(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman LLM"), mainWindow); actionMindWingman->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_Slash)); actionMindWingman->setStatusTip(tr("Open Wingman dialog...")); @@ -205,6 +211,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView) menuMind->addSeparator(); menuMind->addAction(actionMindThink); menuMind->addAction(actionMindAutolink); + menuMind->addAction(actionMindSemanticSearch); menuMind->addAction(actionMindWingman); menuMind->addAction(actionMindTool); menuMind->addAction(actionMindScope); diff --git a/app/src/qt/main_menu_view.h b/app/src/qt/main_menu_view.h index 5f039026..f9423952 100644 --- a/app/src/qt/main_menu_view.h +++ b/app/src/qt/main_menu_view.h @@ -77,6 +77,9 @@ class MainMenuView : public QObject QAction* actionMindRemember; QAction* actionMindThink; QAction* actionMindAutolink; +#ifdef DO_MF_DEBUG + QAction* actionMindSemanticSearch; +#endif QAction* actionMindWingman; QAction* actionMindTool; QAction* actionMindScope; diff --git a/app/src/qt/main_window_presenter.cpp b/app/src/qt/main_window_presenter.cpp index 41b4690c..c317b02b 100644 --- a/app/src/qt/main_window_presenter.cpp +++ b/app/src/qt/main_window_presenter.cpp @@ -666,6 +666,38 @@ void MainWindowPresenter::doActionMindToggleAutolink() } } +void MainWindowPresenter::doActionMindToggleSemanticSearch() +{ + // TODO: to be implemented in analogous way as autolinking + if(config.isSemanticSearch()) { + config.setSemanticSearch(false); + statusBar->showInfo(tr("Semantic search disabled")); + } else { + // check whether possible + if(config.canWingmanOllama()) { + config.setSemanticSearch(true); + statusBar->showInfo(tr("Semantic search activated")); + } else { + config.setSemanticSearch(false); + statusBar->showError(tr("Semantic search cannot be activated - missing dependencies")); + QMessageBox::critical( + &view, + tr("Semantic Search"), + tr("Semantic search cannot be activated - ollama Wingman must be configured.") + ); + return; + } + } + mdConfigRepresentation->save(config); + + // activate semantic search + if(config.isSemanticSearch()) { + statusBar->showInfo(tr("Refresh semantic search index ~ text embeddings of all (modified) Notes...")); + mind->refreshEmbeddings(); + } +} + + void MainWindowPresenter::doActionNameDescFocusSwap() { if(orloj->isFacetActive(OrlojPresenterFacets::FACET_EDIT_OUTLINE_HEADER)) { diff --git a/app/src/qt/main_window_presenter.h b/app/src/qt/main_window_presenter.h index 8396e802..9885092b 100644 --- a/app/src/qt/main_window_presenter.h +++ b/app/src/qt/main_window_presenter.h @@ -195,6 +195,7 @@ public slots: void doActionMindSleep(); void doActionMindToggleThink(); void doActionMindToggleAutolink(); + void doActionMindToggleSemanticSearch(); void doActionMindLearnRepository(); void doActionMindLearnFile(); void doActionMindRelearn(QString path); diff --git a/build/Makefile b/build/Makefile index b03f6dfc..4fa7c836 100644 --- a/build/Makefile +++ b/build/Makefile @@ -147,9 +147,9 @@ build: clean-app ../app/mindforger ## build production MindForger application bi .PHONY: build-dev -build-dev: clean-app ## build development MindForger application binary +build-dev: clean-app ## build development MindForger application binary w/ debug info @echo "Building DEV MindForger executable..." - cd .. && qmake -r mindforger.pro DEFINES+=DO_MF_DEBUG && make -j $(CPU_CORES) ; cd .. + cd .. && qmake -r mindforger.pro CONFIG+=debug DEFINES+=DO_MF_DEBUG && make -j $(CPU_CORES) ; cd .. ifeq ($(UNAME), Darwin) @echo "\nIf build succeeded, then MindForger executable can be found in:\n app/mindforger.app/Contents/MacOS/mindforger" ls -al ../app/mindforger.app/Contents/MacOS/mindforger @@ -204,6 +204,13 @@ else # cd ../app && pwd && ./mindforger /home/dvorka/mf-devel/bug-copy-image endif +run-gdb: build-dev ## run MindForger using gdb +ifeq ($(UNAME), Darwin) + cd ../app/mindforger.app/Contents/MacOS && ./mindforger /Users/dvorka/mf-devel/mf-copy +else + cd ../app && pwd && gdb --args ./mindforger /home/dvorka/mf-devel/library-trainer +endif + # # install # diff --git a/lib/src/config/configuration.cpp b/lib/src/config/configuration.cpp index ffb0be19..ff99e935 100644 --- a/lib/src/config/configuration.cpp +++ b/lib/src/config/configuration.cpp @@ -39,7 +39,7 @@ const string Configuration::DEFAULT_UI_HTML_CSS_THEME = string{UI_DEFAULT_HTML_C const string Configuration::DEFAULT_EDITOR_FONT= string{UI_DEFAULT_EDITOR_FONT}; const string Configuration::DEFAULT_TIME_SCOPE = string{"0y0m0d0h0m"}; const string Configuration::DEFAULT_WINGMAN_LLM_MODEL_OPENAI = string{LLM_MODEL_GPT35_TURBO}; -const string Configuration::DEFAULT_WINGMAN_LLM_MODEL_OLLAMA = string{LLM_MODEL_LLAMA2}; +const string Configuration::DEFAULT_WINGMAN_LLM_MODEL_OLLAMA = string{LLM_MODEL_PHI}; Configuration::Configuration() : asyncMindThreshold{}, @@ -51,6 +51,7 @@ Configuration::Configuration() autolinking{DEFAULT_AUTOLINKING}, autolinkingColonSplit{}, autolinkingCaseInsensitive{}, + semanticSearch{DEFAULT_SEMANTIC_SEARCH}, wingmanProvider{DEFAULT_WINGMAN_LLM_PROVIDER}, wingmanOpenAiApiKey{}, wingmanOpenAiLlm{DEFAULT_WINGMAN_LLM_MODEL_OPENAI}, @@ -151,6 +152,7 @@ void Configuration::clear() autolinking = DEFAULT_AUTOLINKING; autolinkingColonSplit = DEFAULT_AUTOLINKING_COLON_SPLIT; autolinkingCaseInsensitive = DEFAULT_AUTOLINKING_CASE_INSENSITIVE; + semanticSearch = DEFAULT_SEMANTIC_SEARCH; wingmanProvider = DEFAULT_WINGMAN_LLM_PROVIDER; wingmanOpenAiApiKey.clear(); wingmanOpenAiLlm = DEFAULT_WINGMAN_LLM_MODEL_OPENAI; diff --git a/lib/src/config/configuration.h b/lib/src/config/configuration.h index 42229479..d24fa404 100644 --- a/lib/src/config/configuration.h +++ b/lib/src/config/configuration.h @@ -57,6 +57,7 @@ constexpr const auto LLM_MODEL_GPT35_TURBO = "gpt-3.5-turbo"; constexpr const auto LLM_MODEL_GPT4 = "gpt-4"; // TODO ollama does NOT have to host llama2 > it should NOT be offered as default model constexpr const auto LLM_MODEL_LLAMA2 = "llama2"; +constexpr const auto LLM_MODEL_PHI = "phi"; // const in constexpr makes value const constexpr const auto ENV_VAR_HOME = "HOME"; @@ -275,6 +276,8 @@ class Configuration { static constexpr const bool DEFAULT_AUTOLINKING_CASE_INSENSITIVE = true; static constexpr const bool DEFAULT_SAVE_READS_METADATA = true; + static constexpr const bool DEFAULT_SEMANTIC_SEARCH = false; + static constexpr const bool UI_DEFAULT_NERD_TARGET_AUDIENCE = true; static const std::string DEFAULT_STARTUP_VIEW_NAME; static const std::string DEFAULT_UI_THEME_NAME; @@ -343,6 +346,8 @@ class Configuration { bool autolinkingColonSplit; bool autolinkingCaseInsensitive; + bool semanticSearch; + /* Wingman configuration, initialization and use: @@ -544,6 +549,8 @@ class Configuration { void setAutolinkingColonSplit(bool autolinkingColonSplit) { this->autolinkingColonSplit=autolinkingColonSplit; } bool isAutolinkingCaseInsensitive() const { return autolinkingCaseInsensitive; } void setAutolinkingCaseInsensitive(bool autolinkingCaseInsensitive) { this->autolinkingCaseInsensitive=autolinkingCaseInsensitive; } + bool isSemanticSearch() const { return semanticSearch; } + void setSemanticSearch(bool semanticSearch) { this->semanticSearch=semanticSearch; } unsigned int getMd2HtmlOptions() const { return md2HtmlOptions; } AssociationAssessmentAlgorithm getAaAlgorithm() const { return aaAlgorithm; } void setAaAlgorithm(AssociationAssessmentAlgorithm aaa) { aaAlgorithm = aaa; } diff --git a/lib/src/mind/ai/llm/mock_wingman.h b/lib/src/mind/ai/llm/mock_wingman.h index a102e1fe..2d544f8d 100644 --- a/lib/src/mind/ai/llm/mock_wingman.h +++ b/lib/src/mind/ai/llm/mock_wingman.h @@ -48,8 +48,10 @@ class MockWingman: Wingman } std::string getWingmanLlmModel() const { return llmModel; } - virtual void chat(CommandWingmanChat& command) override; + virtual void embeddings(CommandWingmanEmbeddings& command) override { + UNUSED_ARG(command); + } }; diff --git a/lib/src/mind/ai/llm/ollama_wingman.cpp b/lib/src/mind/ai/llm/ollama_wingman.cpp index de27784a..d9a344c0 100644 --- a/lib/src/mind/ai/llm/ollama_wingman.cpp +++ b/lib/src/mind/ai/llm/ollama_wingman.cpp @@ -42,7 +42,7 @@ size_t ollamaCurlWriteCallback(void* contents, size_t size, size_t nmemb, std::s OllamaWingman::OllamaWingman(const string& url) : Wingman(WingmanLlmProviders::WINGMAN_PROVIDER_OLLAMA), - url{url + "/api/generate"}, + url{url}, llmModels{} { } @@ -51,32 +51,122 @@ OllamaWingman::~OllamaWingman() { } -void OllamaWingman::curlListModels() { - if(!this->llmModels.empty()) { - this->llmModels.clear(); - } +void OllamaWingman::listModelsHttpGet() { + string url = + this->url + + (stringEndsWith(this->url, "/")?"":"/") + + "api/tags"; - // call to ollama API to list available models - throw std::runtime_error("OllamaWingman::curlListModels() not implemented"); -} + MF_DEBUG(" ollama: curlGet() url: " << url << endl); + CURL* curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + + std::string responseString; + std::string headerString; + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ollamaCurlWriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseString); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headerString); + + // perform GET request + CURLcode res = curl_easy_perform(curl); + MF_DEBUG(" ollama: curlGet() response: '" << responseString << "'" << endl); -std::vector& OllamaWingman::listModels() -{ - if(this->llmModels.empty()) { - this->curlListModels(); + // clean up + curl_easy_cleanup(curl); + + if (res != CURLE_OK) { + MF_DEBUG(" ollama: curlGet() error: " << curl_easy_strerror(res) << endl); + //command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + //command.errorMessage = curl_easy_strerror(res); + } else { + MF_DEBUG(" ollama: curlGet() OK" << endl); + //command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_OK; + } + + // curl_global_cleanup(); + curl = NULL; + + // parse JSon + /* + { + "models": [ + { + "name": "llama2:latest", + "model": "llama2:latest", + "modified_at": "2024-03-02T09:59:31.011931063+01:00", + "size": 3826793677, + "digest": "78e26419b4469263f75331927a00a0284ef6544c1975b826b15abdaef17bb962", + "details": { + "parent_model": "", + "format": "gguf", + "family": "llama", + "families": [ + "llama" + ], + "parameter_size": "7B", + "quantization_level": "Q4_0" + } + }, + ... + } + */ + // parse json + nlohmann::json httpResponseJSon; + try { + httpResponseJSon = nlohmann::json::parse(responseString); + } catch (...) { + // catch ALL exceptions + MF_DEBUG( + "Error: unable to parse ollama JSon response:" << endl << + "'" << responseString << "'" << endl + ); + // TODO: create command so that I can transfer all the fields + //command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + //command.errorMessage = "Error: unable to parse ollama JSon response: '" + command.httpResponse + "'"; + //command.answerMarkdown.clear(); + //command.answerTokens = 0; + //command.answerLlmModel = llmModel; + + return; + } + + MF_DEBUG( + "OllamaWingman::curlGet() parsed response:" << endl + << ">>>" + << httpResponseJSon.dump(4) + << "<<<" + << endl); + + MF_DEBUG("OllamaWingman::curlGet() fields:" << endl); + if(httpResponseJSon.contains("models")) { + for(const auto& item : httpResponseJSon["models"].items()) { + MF_DEBUG(" item: " << item.key() << endl); + if(item.value().contains("name")) { + MF_DEBUG(" name: " << item.value()["name"] << endl); + string llmModelName{item.value()["name"]}; + // add model to list + this->llmModels.push_back(llmModel); + } + } + } } - return this->llmModels; + MF_DEBUG(" DONE ollama: curlGet() url: " << url << endl); } /** - * OpenAI cURL GET request. + * cURL / Qt Network POST request. * * @see https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-completion * @see https://github.com/ollama/ollama/blob/main/docs/api.md#list-local-models * @see https://ollama.com/library/llama2 * @see https://json.nlohmann.me/ */ -void OllamaWingman::curlGet(CommandWingmanChat& command) { +void OllamaWingman::chatHttpPost(CommandWingmanChat& command) { #if !defined(__APPLE__) && !defined(_WIN32) CURL* curl = curl_easy_init(); if (curl) { @@ -102,8 +192,13 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { string requestJSonStr = requestJSon.dump(4); + string url = + this->url + + (stringEndsWith(this->url, "/")?"":"/") + + "api/generate"; + MF_DEBUG( - "OllamaWingman::curlGet() promptJSon:" << endl + "OllamaWingman::curlPost() promptJSon: " << url << endl << ">>>" << requestJSonStr << "<<<" @@ -112,7 +207,7 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { #if defined(_WIN32) || defined(__APPLE__) QNetworkAccessManager networkManager; - QNetworkRequest request(QUrl(QString::fromStdString(this->url))); + QNetworkRequest request(QUrl(QString::fromStdString(url))); request.setHeader( QNetworkRequest::ContentTypeHeader, "application/json"); @@ -160,11 +255,11 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { " '" << command.httpResponse << "'" << endl); } #else - // set up cURL options + // set up cURL options: POST command.httpResponse.clear(); curl_easy_setopt( curl, CURLOPT_URL, - this->url.c_str()); + url.c_str()); curl_easy_setopt( curl, CURLOPT_POSTFIELDS, requestJSonStr.c_str()); @@ -175,7 +270,7 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { curl, CURLOPT_WRITEDATA, &command.httpResponse); - // perform the request + // perform POST request CURLcode res = curl_easy_perform(curl); // clean up @@ -231,7 +326,7 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { } catch (...) { // catch ALL exceptions MF_DEBUG( - "Error: unable to parse OpenAI JSon response:" << endl << + "Error: unable to parse ollama JSon response:" << endl << "'" << command.httpResponse << "'" << endl ); @@ -245,13 +340,13 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { } MF_DEBUG( - "OllamaWingman::curlGet() parsed response:" << endl + "OllamaWingman::curlPost() parsed response:" << endl << ">>>" << httpResponseJSon.dump(4) << "<<<" << endl); - MF_DEBUG("OllamaWingman::curlGet() fields:" << endl); + MF_DEBUG("OllamaWingman::curlPost() fields:" << endl); if(httpResponseJSon.contains("model")) { httpResponseJSon["model"].get_to(command.answerLlmModel); MF_DEBUG(" model: " << command.answerLlmModel << endl); @@ -285,17 +380,233 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) { else { command.status = m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; command.errorMessage.assign( - "ollama API HTTP request failed: unable to initialize cURL"); + "ollama API HTTP request to chat failed: unable to initialize cURL"); } #endif } -void OllamaWingman::chat(CommandWingmanChat& command) { - MF_DEBUG("OllamaWingman::chat() prompt:" << endl << command.prompt << endl); +void OllamaWingman::embeddingsHttpPost(CommandWingmanEmbeddings& command) { + // empty prompt - empty vector + if(command.prompt.empty()) { + command.httpResponse.clear(); + command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_OK; + command.errorMessage.clear(); + command.answerLlmModel = llmModel; + command.answerEmbeddings.clear(); + + return; + } + +#if !defined(__APPLE__) && !defined(_WIN32) + CURL* curl = curl_easy_init(); + if (curl) { +#endif + // TODO: remove escape if not needed + //string escapedPrompt{command.prompt}; + //replaceAll("\n", " ", escapedPrompt); + //replaceAll("\"", "\\\"", escapedPrompt); + + /* + ollama API JSon request example: + + curl -X POST http://localhost:11434/api/embeddings -d '{ + "model": "llama2", + "prompt":"Why is the sky blue?", + }' + + */ + nlohmann::json requestJSon; + requestJSon["model"] = llmModel; + requestJSon["prompt"] = command.prompt; + + string requestJSonStr = requestJSon.dump(4); + + string url = + this->url + + (stringEndsWith(this->url, "/")?"":"/") + + "api/embeddings"; + + MF_DEBUG( + "OllamaWingman::curlPost() promptJSon: '" << url << "'" << endl + << ">>>" + << requestJSonStr + << "<<<" + << endl); + +#if defined(_WIN32) || defined(__APPLE__) + QNetworkAccessManager networkManager; + + QNetworkRequest request(QUrl(QString::fromStdString(url))); + request.setHeader( + QNetworkRequest::ContentTypeHeader, + "application/json"); + + QNetworkReply* reply = networkManager.post( + request, + requestJSonStr.c_str() + ); + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + reply->deleteLater(); + + command.status = m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_OK; + + // response: error handling + auto error = reply->error(); + if(error != QNetworkReply::NoError) { + command.errorMessage = + "Error: request to ollama Wingman provider failed due a network error - " + + reply->errorString().toStdString(); + MF_DEBUG(command.errorMessage << endl); + command.status = m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + } + QByteArray read; + if(command.status == m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_OK) { + read = reply->readAll(); + + if(read.isEmpty()) { + command.errorMessage = + "Error: Request to ollama Wingman provider failed - response is empty'"; + MF_DEBUG(command.errorMessage << endl); + command.status = m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + } + } - curlGet(command); + // response: successful response processing + if(command.status == m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_OK) { + QString qCommandResponse = QString{read}; + command.httpResponse = qCommandResponse.toStdString(); + command.errorMessage.clear(); + command.status = m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_OK; + MF_DEBUG( + "Successful ollama Wingman provider response:" << endl << + " '" << command.httpResponse << "'" << endl); + } +#else + // set up cURL options: POST + command.httpResponse.clear(); + curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1); + curl_easy_setopt( + curl, CURLOPT_URL, + url.c_str()); + curl_easy_setopt( + curl, CURLOPT_POSTFIELDS, + requestJSonStr.c_str()); + curl_easy_setopt( + curl, CURLOPT_WRITEFUNCTION, + ollamaCurlWriteCallback); + curl_easy_setopt( + curl, CURLOPT_WRITEDATA, + &command.httpResponse); + + // perform POST request + CURLcode res = curl_easy_perform(curl); + + // clean up + curl_easy_cleanup(curl); + + if (res != CURLE_OK) { + command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + command.errorMessage = curl_easy_strerror(res); + } else { + command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_OK; + } +#endif + + // finish error handling (shared by QNetwork/CURL) + if(command.status == WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR) { + std::cerr << + "Error: Wingman ollama cURL/QtNetwork request to get embeddings " + "failed (error message/HTTP response):" << endl << + " '" << command.errorMessage << "'" << endl << + " '" << command.httpResponse << "'" << endl; + + command.answerLlmModel = llmModel; + command.answerEmbeddings.clear(); + + return; + } + + // parse JSon + /* + ollama API JSon response example: + + { + "embedding": [ + 0.8623529076576233, + ... + 0.8623529076576233 + ] + } + + */ + + // parse response string to JSon object + nlohmann::json httpResponseJSon; + try { + httpResponseJSon = nlohmann::json::parse(command.httpResponse); + } catch (...) { + // catch ALL exceptions + MF_DEBUG( + "Error: unable to parse ollama JSon response:" << endl << + "'" << command.httpResponse << "'" << endl + ); + + command.status = WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + command.errorMessage = "Error: unable to parse ollama JSon response: '" + command.httpResponse + "'"; + command.answerLlmModel = llmModel; + command.answerEmbeddings.clear(); + + return; + } + + /* + MF_DEBUG( + "OllamaWingman::curlPost() parsed response:" << endl + << ">>>" + << httpResponseJSon.dump(4) + << "<<<" + << endl); + */ + + // MF_DEBUG("OllamaWingman::curlPost() fields:" << endl); + if(httpResponseJSon.contains("embedding")) { + for(const auto& item : httpResponseJSon["embedding"].items()) { + // MF_DEBUG(" item #" << item.key() << ": " << item.value() << endl); + command.answerEmbeddings.push_back(item.value()); + } + // MF_DEBUG(" EMBEDDINGS vector: " << command.answerEmbeddings.size() << endl); + } +#ifdef MF_DEBUG + else { + MF_DEBUG(" EMBEDDINGS: 'embedding' key not found in" << endl); + } +#endif + +#if !defined(__APPLE__) && !defined(_WIN32) + } + else { + command.status = m8r::WingmanStatusCode::WINGMAN_STATUS_CODE_ERROR; + command.errorMessage.assign( + "ollama API HTTP request to get embeddings failed: unable to initialize cURL"); + } +#endif +} + +std::vector& OllamaWingman::listModels() +{ + listModelsHttpGet(); + + return this->llmModels; +} + +void OllamaWingman::chat(CommandWingmanChat& command) { + chatHttpPost(command); +} - MF_DEBUG("OllamaWingman::chat() answer:" << endl << command.answerMarkdown << endl); +void OllamaWingman::embeddings(CommandWingmanEmbeddings& command) { + embeddingsHttpPost(command); } } // m8r namespace diff --git a/lib/src/mind/ai/llm/ollama_wingman.h b/lib/src/mind/ai/llm/ollama_wingman.h index af2d1558..6d8e42cc 100644 --- a/lib/src/mind/ai/llm/ollama_wingman.h +++ b/lib/src/mind/ai/llm/ollama_wingman.h @@ -45,8 +45,9 @@ class OllamaWingman: Wingman std::string url; std::vector llmModels; - void curlListModels(); - void curlGet(CommandWingmanChat& command); + void listModelsHttpGet(); + void chatHttpPost(CommandWingmanChat& command); + void embeddingsHttpPost(CommandWingmanEmbeddings& command); public: explicit OllamaWingman(const std::string& url); @@ -58,6 +59,7 @@ class OllamaWingman: Wingman virtual std::vector& listModels() override; virtual void chat(CommandWingmanChat& command) override; + virtual void embeddings(CommandWingmanEmbeddings& command) override; }; } diff --git a/lib/src/mind/ai/llm/openai_wingman.h b/lib/src/mind/ai/llm/openai_wingman.h index 729e5f0d..b9055462 100644 --- a/lib/src/mind/ai/llm/openai_wingman.h +++ b/lib/src/mind/ai/llm/openai_wingman.h @@ -70,6 +70,14 @@ class OpenAiWingman: Wingman * @brief Chat with configured LLM model. */ virtual void chat(CommandWingmanChat& command) override; + + /** + * @brief Get embeddings from configured LLM model. + */ + virtual void embeddings(CommandWingmanEmbeddings& command) override { + UNUSED_ARG(command); + throw std::runtime_error("OpenAI Wingman does not support embeddings"); + } }; } diff --git a/lib/src/mind/ai/llm/wingman.h b/lib/src/mind/ai/llm/wingman.h index c8757d3b..52b6cffb 100644 --- a/lib/src/mind/ai/llm/wingman.h +++ b/lib/src/mind/ai/llm/wingman.h @@ -72,7 +72,7 @@ enum WingmanStatusCode { /** * Wingman chat request command pattern must be used as asynchronous requests. - * As it annot handle that many parameters this structure is used. + * As it cannot handle that many parameters this structure is used. */ struct CommandWingmanChat { std::string prompt; @@ -85,6 +85,19 @@ struct CommandWingmanChat { std::string answerMarkdown; }; +/** + * Wingman embeddings request command pattern must be used as asynchronous requests. + * As it vannot handle that many parameters this structure is used. + */ +struct CommandWingmanEmbeddings { + std::string prompt; + std::string httpResponse; + WingmanStatusCode status; + std::string errorMessage; + std::string answerLlmModel; + std::vector answerEmbeddings; +}; + /** * Wingman is a class that provides a set of LLM-based use cases. @@ -172,6 +185,11 @@ class Wingman * @brief Chat with LLM model specified by the 'command'. */ virtual void chat(CommandWingmanChat& command) = 0; + + /** + * @brief Get document embeddings for given prompt. + */ + virtual void embeddings(CommandWingmanEmbeddings& command) = 0; }; } diff --git a/lib/src/mind/mind.cpp b/lib/src/mind/mind.cpp index e4ecfaa0..1fba1d4b 100644 --- a/lib/src/mind/mind.cpp +++ b/lib/src/mind/mind.cpp @@ -1476,6 +1476,7 @@ void Mind::initWingman() wingman = nullptr; } wingman = (Wingman*)new OllamaWingman{config.getWingmanOllamaUrl()}; + wingman->listModels(); wingman->setLlmModel(config.getWingmanOllamaLlm()); wingmanLlmProvider = config.getWingmanLlmProvider(); return; @@ -1593,4 +1594,70 @@ CommandWingmanChat Mind::wingmanChat(CommandWingmanChat& command) return command; } +void Mind::refreshEmbeddings() +{ + MF_DEBUG("MIND: Refreshing embeddings..." << endl); + if(getWingman()) { + vector allNotes{}; + memory.getAllNotes(allNotes); +#ifdef MF_DEBUG + int embeddingsSizeB=0; + int counter=0; + MF_DEBUG(" Embedding for " << allNotes.size() << " Notes:" << endl); +#endif + auto beginTs = chrono::high_resolution_clock::now(); + for(Note* n:allNotes) { + MF_DEBUG( + " " << + ++counter << "/" << allNotes.size() << + " getting embeddings for '" << n->getName() << "'" << endl); + + CommandWingmanEmbeddings command{}; + command.prompt = n->getDescriptionAsString(); + // TODO: truncate text + + // TODO: calculate embeddings ONLY if not in cache (timestamp not changed) + + getWingman()->embeddings(command); +#ifdef MF_DEBUG + if(command.answerEmbeddings.size()) { + embeddingsSizeB += command.answerEmbeddings.size()*sizeof(command.answerEmbeddings[0]); + } +#endif + // TODO: store embeddings to embeddings cache: note key -> modified/embeddings vector + } +#ifdef MF_DEBUG + auto endTs = chrono::high_resolution_clock::now(); + auto duration = chrono::duration_cast(endTs - beginTs); + auto nDuration = to_string(float(duration.count()) / float(allNotes.size())); + auto nps = to_string(1000.0 / (float(duration.count()) / float(allNotes.size()))); + MF_DEBUG( + "Embeddings of " << + allNotes.size() << + " Notes via LLM in " << + to_string(duration.count()) << "ms" << + " (" << nDuration << "ms/N) " << + " (" << nps << "N/s)" << + endl); + MF_DEBUG( + "Embeddings size of " << allNotes.size() << " Notes: " << + stringIntFormat(std::to_string(embeddingsSizeB)) << " bytes " << + "(" << stringIntFormat( + std::to_string( + int( + float(embeddingsSizeB) / float(allNotes.size())))) << " bytes/N)" << + endl + ); + + // BENCHMARK: + // - production repository: 15.000 Notes + // - ~7 Notes / second + // - 38' for 15.000 Notes + // - 250MB embedding vectors cache for 15.000 Notes > 16kB/Note +#endif + } + + MF_DEBUG("MIND: DONE refreshing embeddings" << endl); +} + } /* namespace */ diff --git a/lib/src/mind/mind.h b/lib/src/mind/mind.h index dc12d650..5197a0ed 100644 --- a/lib/src/mind/mind.h +++ b/lib/src/mind/mind.h @@ -700,6 +700,10 @@ class Mind : public OntologyProvider */ Wingman* getWingman(); CommandWingmanChat wingmanChat(CommandWingmanChat& command); + /** + * @brief Use ollama Wingman to refresh text embeddings for all Notes. + */ + void refreshEmbeddings(); /* * DIAGNOSTICS diff --git a/lib/src/representations/markdown/markdown_configuration_representation.cpp b/lib/src/representations/markdown/markdown_configuration_representation.cpp index 1cfd8a96..bf9dfe3e 100644 --- a/lib/src/representations/markdown/markdown_configuration_representation.cpp +++ b/lib/src/representations/markdown/markdown_configuration_representation.cpp @@ -34,6 +34,7 @@ constexpr const auto CONFIG_SETTING_MIND_TIME_SCOPE_LABEL = "* Time scope: "; constexpr const auto CONFIG_SETTING_MIND_TAGS_SCOPE_LABEL = "* Tags scope: "; constexpr const auto CONFIG_SETTING_MIND_DISTRIBUTOR_INTERVAL = "* Async refresh interval (ms): "; constexpr const auto CONFIG_SETTING_MIND_AUTOLINKING = "* Autolinking: "; +constexpr const auto CONFIG_SETTING_MIND_SEMANTIC_SEARCH = "* Semantic search: "; constexpr const auto CONFIG_SETTING_MIND_WINGMAN_PROVIDER = "* Wingman LLM provider: "; constexpr const auto CONFIG_SETTING_MIND_OPENAI_KEY = "* Wingman's OpenAI API key: "; constexpr const auto CONFIG_SETTING_MIND_OPENAI_LLM = "* Wingman's OpenAI LLM model: "; @@ -405,6 +406,12 @@ void MarkdownConfigurationRepresentation::configurationSection( } else { c.setAutolinking(false); } + } else if(line->find(CONFIG_SETTING_MIND_SEMANTIC_SEARCH) != std::string::npos) { + if(line->find("yes") != std::string::npos) { + c.setSemanticSearch(true); + } else { + c.setSemanticSearch(false); + } } else if(line->find(CONFIG_SETTING_MIND_WINGMAN_PROVIDER) != std::string::npos) { if(line->find( c.getWingmanLlmProviderAsString( @@ -522,6 +529,8 @@ string& MarkdownConfigurationRepresentation::to(Configuration* c, string& md) " * Examples: 500, 1000, 3000, 5000" << endl << CONFIG_SETTING_MIND_AUTOLINKING << (c?(c->isAutolinking()?"yes":"no"):(Configuration::DEFAULT_AUTOLINKING?"yes":"no")) << endl << " * Examples: yes, no" << endl << + CONFIG_SETTING_MIND_SEMANTIC_SEARCH << (c?(c->isSemanticSearch()?"yes":"no"):(Configuration::DEFAULT_SEMANTIC_SEARCH?"yes":"no")) << endl << + " * Examples: yes, no" << endl << CONFIG_SETTING_MIND_WINGMAN_PROVIDER << Configuration::getWingmanLlmProviderAsString(c?c->getWingmanLlmProvider():Configuration::DEFAULT_WINGMAN_LLM_PROVIDER) << endl << " * Examples: none, openai, ollama" << endl << CONFIG_SETTING_MIND_OPENAI_KEY << (c?c->getWingmanOpenAiApiKey():"") << endl <<