Skip to content

Commit

Permalink
WIP: library orphans search
Browse files Browse the repository at this point in the history
  • Loading branch information
dvorka committed Apr 1, 2024
1 parent f7c4a4e commit 20f6210
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 22 deletions.
3 changes: 2 additions & 1 deletion app/src/qt/dialogs/configuration_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ ConfigurationDialog::WingmanOpenAiTab::WingmanOpenAiTab(QWidget* parent, QComboB
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();
llmModelsCombo->addItem(LLM_MODEL_NONE);
Expand Down Expand Up @@ -1006,7 +1007,7 @@ void ConfigurationDialog::WingmanTab::handleComboBoxChanged(int index) {
tr(
"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."));
"when you use Wingman."));
}
}

Expand Down
1 change: 1 addition & 0 deletions app/src/qt/main_menu_presenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ MainMenuPresenter::MainMenuPresenter(MainWindowPresenter* mwp)
// menu: Library
QObject::connect(view->actionLibraryAdd, SIGNAL(triggered()), mwp, SLOT(doActionLibraryNew()));
QObject::connect(view->actionLibrarySync, SIGNAL(triggered()), mwp, SLOT(doActionLibrarySync()));
QObject::connect(view->actionLibraryOrphans, SIGNAL(triggered()), mwp, SLOT(doActionLibraryOrphans()));
QObject::connect(view->actionLibraryDeprecate, SIGNAL(triggered()), mwp, SLOT(doActionLibraryRm()));

// menu: Organizer
Expand Down
16 changes: 12 additions & 4 deletions app/src/qt/main_menu_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView)
actionMindAutolink->setVisible(false);
#endif

actionMindWingman = new QAction(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman GPT"), mainWindow);
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..."));

Expand Down Expand Up @@ -140,6 +140,13 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView)
tr(
"Synchronize library source directory with MindForger notebook(s) which represent"
"library resources..."));
// library: find orphans
actionLibraryOrphans = new QAction(
QIcon(":/menu-icons/find.svg"),
tr("&Find orphans"),
mainWindow);
actionLibrarySync->setStatusTip(
tr("Find library Notebooks which reference non-existent documents..."));
// library: deprecate
actionLibraryDeprecate = new QAction(
QIcon(":/menu-icons/delete.svg"), tr("&Delete library"), mainWindow);
Expand All @@ -148,6 +155,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView)
// assemble Library sub-menu
submenuMindLibrary->addAction(actionLibraryAdd);
submenuMindLibrary->addAction(actionLibrarySync);
submenuMindLibrary->addAction(actionLibraryOrphans);
submenuMindLibrary->addAction(actionLibraryDeprecate);

// dream ... sanity, integrity, detox, inference, assoc discovery, ...
Expand Down Expand Up @@ -565,7 +573,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView)
actionOutlineTWikiImport->setStatusTip(tr("Import Notebook from an external TWiki file and restart MindForger"));
submenuOutlineImport->addAction(actionOutlineTWikiImport);

submenuOutlineWingman = menuOutline->addMenu(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman GPT"));
submenuOutlineWingman = menuOutline->addMenu(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman LLM"));
actionOutlineWingmanSummarize = new QAction(tr("&Summarize"), mainWindow);
actionOutlineWingmanSummarize->setStatusTip(tr("Ask Wingman to summarize text of the Notebook..."));
submenuOutlineWingman->addAction(actionOutlineWingmanSummarize);
Expand Down Expand Up @@ -699,7 +707,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView)
actionNoteImport->setStatusTip(tr("Import Note from an external file in a supported format"));
actionNoteImport->setEnabled(false);

submenuNoteWingman = menuNote->addMenu(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman GPT"));
submenuNoteWingman = menuNote->addMenu(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman LLM"));
actionNoteWingmanSummarize = new QAction(tr("&Summarize"), mainWindow);
actionNoteWingmanSummarize->setStatusTip(tr("Ask Wingman to summarize text of the Note..."));
submenuNoteWingman->addAction(actionNoteWingmanSummarize);
Expand Down Expand Up @@ -788,7 +796,7 @@ MainMenuView::MainMenuView(MainWindowView& mainWindowView)
actionEditSpellCheck = new QAction(QIcon(":/menu-icons/paste.svg"), tr("&Spell Check"), mainWindow);
actionEditSpellCheck->setStatusTip(tr("Spell check Notebook or Note description"));

submenuEditWingman = menuEdit->addMenu(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman GPT"));
submenuEditWingman = menuEdit->addMenu(QIcon(":/menu-icons/wingman-green.svg"), tr("&Wingman LLM"));
actionEditWingmanFixGrammar = new QAction(tr("&Fix Grammar"), mainWindow);
actionEditWingmanFixGrammar->setStatusTip(tr("Ask Wingman to fix grammar errors in the selected text / word under the cursor..."));
submenuEditWingman->addAction(actionEditWingmanFixGrammar);
Expand Down
1 change: 1 addition & 0 deletions app/src/qt/main_menu_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class MainMenuView : public QObject
QMenu* submenuMindLibrary;
QAction* actionLibraryAdd;
QAction* actionLibrarySync;
QAction* actionLibraryOrphans;
QAction* actionLibraryDeprecate;
QAction* actionMindPreferences;
QMenu* submenuMindExport;
Expand Down
10 changes: 7 additions & 3 deletions app/src/qt/main_window_presenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2176,13 +2176,13 @@ void MainWindowPresenter::slotRunWingmanFromDialog(bool showDialog)

// check the result
if (future.isFinished()) {
statusBar->showInfo(QString(tr("Wingman received an answer from the GPT provider")));
statusBar->showInfo(QString(tr("Wingman received an answer from the LLM provider")));
} else {
statusBar->showError(QString(tr("Wingman failed to receive an answer from the GPT provider")));
statusBar->showError(QString(tr("Wingman failed to receive an answer from the LLM provider")));

// PUSH answer to the chat dialog
this->wingmanDialog->appendAnswerToChat(
"Wingman failed to get answer from the GPT provider.<br/><br/>"+commandWingmanChat.answerMarkdown,
"Wingman failed to get answer from the LLM provider.<br/><br/>"+commandWingmanChat.answerMarkdown,
"",
this->wingmanDialog->getContextType(),
true
Expand Down Expand Up @@ -3464,6 +3464,10 @@ void MainWindowPresenter::handleSyncLibrary()
rmLibraryDialog->reset();
}

void MainWindowPresenter::doActionLibraryOrphans()
{
mind->findLibraryOrphanOs();
}

void MainWindowPresenter::doActionLibraryRm()
{
Expand Down
1 change: 1 addition & 0 deletions app/src/qt/main_window_presenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ public slots:
void doActionLibraryNew();
void handleNewLibrary();
void doActionLibrarySync();
void doActionLibraryOrphans();
void handleSyncLibrary();
void doActionLibraryRm();
void handleRmLibrary();
Expand Down
7 changes: 1 addition & 6 deletions app/src/qt/main_window_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,8 @@ MainWindowView::MainWindowView(LookAndFeels& lookAndFeel)
: QMainWindow(nullptr), // main window has no parent - it is destroyed by main MF class
lookAndFeel(lookAndFeel)
{
#ifdef MF_LLAMA_CPP
#define MINDFORGER_GPT " GPT"
#else
#define MINDFORGER_GPT ""
#endif
windowTitleSkeleton
= "MindForger" MINDFORGER_GPT " - "
= "MindForger - "
+tr("Thinking Notebook")+" - "
+MINDFORGER_VERSION;

Expand Down
6 changes: 3 additions & 3 deletions lib/src/mind/ai/llm/ollama_wingman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ void OllamaWingman::curlListModels() {
if(!this->llmModels.empty()) {
this->llmModels.clear();
}

// call to ollama API to list available models
throw std::runtime_error("OllamaWingman::curlListModels() not implemented");
}

std::vector<std::string>& OllamaWingman::listModels()
std::vector<std::string>& OllamaWingman::listModels()
{
if(this->llmModels.empty()) {
this->curlListModels();
Expand Down Expand Up @@ -258,7 +258,7 @@ void OllamaWingman::curlGet(CommandWingmanChat& command) {
}
if(httpResponseJSon.contains("response")) {
httpResponseJSon["response"].get_to(command.answerMarkdown);
// TODO ask GPT for HTML formatted response
// TODO ask LLM for HTML formatted response
m8r::replaceAll(
"\n",
"<br/>",
Expand Down
4 changes: 3 additions & 1 deletion lib/src/mind/ai/llm/openai_wingman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void OpenAiWingman::curlGet(CommandWingmanChat& command) {
*/
nlohmann::json messageSystemJSon{};
messageSystemJSon["role"] = "system"; // system (instruct GPT who it is), user (user prompts), assistant (GPT answers)
messageSystemJSon["role"] = "system"; // system (instruct LLM who it is), user (user prompts), assistant (LLM answers)
messageSystemJSon["content"] =
// "You are a helpful assistant that returns HTML-formatted answers to the user's prompts."
"You are a helpful assistant."
Expand Down Expand Up @@ -196,6 +196,8 @@ void OpenAiWingman::curlGet(CommandWingmanChat& command) {
" '" << command.httpResponse << "'" << endl);
}
#else
// TODO refactor this section to a generic CURL call which gets: URL, body as C string and returns httpResponse

// set up cURL options
command.httpResponse.clear();
curl_easy_setopt(
Expand Down
47 changes: 47 additions & 0 deletions lib/src/mind/mind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,53 @@ void Mind::initWingman()
wingmanLlmProvider = WingmanLlmProviders::WINGMAN_PROVIDER_NONE;
}

void Mind::findLibraryOrphanOs()
{
vector<Outline*> orphanOutlines{};
const vector<Outline*>& outlines = memory.getOutlines();
const Tag* t = memory.getOntology().findOrCreateTag(
MarkdownDocumentRepresentation::TAG_LIB_DOC);
MF_DEBUG("Searching ORPHAN library outlines..." << endl);
for(Outline* outline:outlines) {
if(!outline->hasTag(t)) {
continue;
}

const vector<string*>& d = outline->getDescription();
if(d.size()>0) {
if(d[0]->size() > 0) {
// MF_DEBUG(" Orphan: 1st line '" << *d[0] << "'" << endl);
if(stringStartsWith(*d[0], MarkdownDocumentRepresentation::PREFIX_1ST_LINE)) {
// extract Markdown link
size_t i{strlen(MarkdownDocumentRepresentation::PREFIX_1ST_LINE)};
string s{
d[0]->substr(
i,
d[0]->size()-i)};
// MF_DEBUG(" '" << s << "'" << endl);

// parse Markdown link
string documentPath{};
if(s.size()>4 && s[0]=='[' && s[s.size()-1]==')') {
size_t i;
if((i=s.find("](")) != std::string::npos) {
documentPath = s.substr(i+2,s.size()-3-i);
}
}
if(documentPath.size()) {
MF_DEBUG(" '" << documentPath << "'" << endl);
if(!isFile(documentPath.c_str())) {
MF_DEBUG(" ORPHAN" << endl);
// TODO
detect whether the file exists
}
}
}
}
}
}
}

Wingman* Mind::getWingman()
{
if(this->wingmanLlmProvider != config.getWingmanLlmProvider()) {
Expand Down
10 changes: 10 additions & 0 deletions lib/src/mind/mind.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "../config/configuration.h"
#include "../representations/representation_interceptor.h"
#include "../representations/markdown/markdown_configuration_representation.h"
#include "../representations/markdown/markdown_document_representation.h"

namespace m8r {

Expand Down Expand Up @@ -685,6 +686,15 @@ class Mind : public OntologyProvider
*/
void noteOnRename(const std::string& oldName, const std::string& newName);

/*
* LIBRARY (information source)
*/

/**
* @brief Find Os which reference non-existent documents.
*/
void findLibraryOrphanOs();

/*
* WINGMAN
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ Outline* MarkdownDocumentRepresentation::to(
}

o->addTag(ontology.findOrCreateTag("pdf"));
o->addTag(ontology.findOrCreateTag("library-document"));
o->addTag(ontology.findOrCreateTag(TAG_LIB_DOC));

o->addDescriptionLine(
new string{
"This is a notebook for the document: "
"[" + documentPath + "](" + documentPath + ")"});
string{PREFIX_1ST_LINE} + "[" + documentPath + "](" + documentPath + ")"});
o->addDescriptionLine(new string{""});
o->addDescriptionLine(new string{"---"});
o->addDescriptionLine(new string{""});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ namespace m8r {

class MarkdownDocumentRepresentation
{
public:

static constexpr const auto TAG_LIB_DOC = "library-document";

static constexpr const auto PREFIX_1ST_LINE = "This is a notebook for the document: ";

private:
Ontology& ontology;

Expand Down
2 changes: 1 addition & 1 deletion lib/test/src/json/json_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ TEST(JSonTestCase, ParseOpenAiResponse)
&& choice["message"].contains("content")
) {
choice["message"]["content"].get_to(answerMarkdown);
// TODO ask GPT for HTML formatted response
// TODO ask LLM for HTML formatted response
m8r::replaceAll(
"\n",
"<br/>",
Expand Down

0 comments on commit 20f6210

Please sign in to comment.