Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added docker fixes and local embedding generation #3

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ This plugin is licensed under the [MIT License](https://github.com/lusob/obsidia

### © Privacy

The OpenAI API is used by brAIn to generate the vector store during ingestion and to answer each question asked in the chat, but its [API usage policies](https://openai.com/policies/api-data-usage-policies ) guarantee to us that OpenAI will not use data submitted by customers via its API to train or improve their models and any data submitted via API will be deleted after 30 days.
By defauls the embeddings as generated locally so your docs are not leaving your machine, in case you check the OpenAI Embeddings check in settings, The OpenAI API is used by brAIn to generate the vector store during ingestion and to answer each question asked in the chat, but its [API usage policies](https://openai.com/policies/api-data-usage-policies ) guarantee to us that OpenAI will not use data submitted by customers via its API to train or improve their models and any data submitted via API will be deleted after 30 days.

### ⚠️ Limitations

During the ingestion (embedding generation) a big amount of notes in your vault can lead to high expenses (~ 1000 notes = 1$), monitor your account and set API key limits to avoid scares
If you are generating the embeddings locally it could consume a lot of time and hardware resources (depending of your marchines and the number of documents)
In case you want to generate the embeddings in OpenAI during the ingestion (embedding generation) a big amount of notes in your vault can lead to high expenses (~ 1000 notes = 1$), monitor your account and set API key limits to avoid scares

### 🐞 Known Issues

brAIn may occasionally generate incorrect or irrelevant content based on the user's input. Additionally, it may encounter errors when calling the OpenAI API if the API key is invalid or if there are issues with the OpenAI API service.

### ⏭ Next

The final idea is to create a complete offline chatbot using an LLM, but so far the hardware requirements for these models are too high.
48 changes: 37 additions & 11 deletions main.js

Large diffs are not rendered by default.

56 changes: 43 additions & 13 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { Docker, Options } from 'docker-cli-js';
import { App, Modal, Notice, Plugin, PluginSettingTab, Setting, addIcon, requestUrl } from 'obsidian';
interface BrainSettings {
openaiApiKey: string;
useOpenAIEmbeddings: boolean; // Add this line
}

const DEFAULT_SETTINGS: BrainSettings = {
openaiApiKey: ''
openaiApiKey: '',
useOpenAIEmbeddings: false // Add this line
};

export default class Brain extends Plugin {
Expand Down Expand Up @@ -79,7 +81,7 @@ export default class Brain extends Plugin {
modal.open();
} else {
// Show an error message if the brAIn web interface is not available
new Notice('brAIn is not running, please check that the port 9000 is not being used by other service');
new Notice('brAIn is not running, check that you have run the ingest command first and also that no other services are using port 9000');
}
this.loadingModal.close();

Expand Down Expand Up @@ -151,10 +153,10 @@ export default class Brain extends Plugin {

try {
// Check if Docker is installed by running "docker --version" command
execSync('docker --version');
execSync('docker --version', { stdio: 'pipe', env: { PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin' }});
} catch (error) {
// Docker is not installed, show a dialog
console.error('Docker is not installed in the system.');
console.error('Docker is not installed in the system. Error: ' + error);
// You can use a dialog library or show an alert using the browser's window object
new Notice('Docker is not installed in the system, brAIn plugin need docker to run.');
}
Expand All @@ -181,19 +183,25 @@ export default class Brain extends Plugin {
/* machineName */ undefined,
/* currentWorkingDirectory */ undefined,
/* echo*/ true,

{PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'}
);

const docker = new Docker(options);
const vaultPath = (this.app.vault.adapter as any).basePath

// Use Docker-CLI-JS to run the container
console.log("Running brain container...")
try {
await docker.command(`rm brain`)
} catch (err) {
console.log('Failed removing container: ' + err.message);
}
try {
await docker.command(`rm brain || true`)
await docker.command(`run -d --name brain -p 9000:9000 -v ${vaultPath}:${vaultPath} -e MARKDOWN_FILES=${vaultPath} -e OPENAI_API_KEY=${openaiApiKey} -e IS_OBSIDIAN_VAULT=1 -t lusob04/brain`);
let output = await docker.command(`run -d --name brain -p 9000:9000 -v ${vaultPath}:${vaultPath} -e MARKDOWN_FILES=${vaultPath} -e OPENAI_API_KEY=${openaiApiKey} -e IS_OBSIDIAN_VAULT=1 -t lusob04/brain`);
console.log('Run brain output: ' + JSON.stringify(output))
} catch (err) {
// Handle error during creation process
console.log('Failed to start brAIn: ' + err.message);
}

}

async runIngestDocs(openaiApiKey: string) {
Expand All @@ -202,16 +210,27 @@ export default class Brain extends Plugin {
/* machineName */ undefined,
/* currentWorkingDirectory */ undefined,
/* echo*/ true,
{PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'}
);

const docker = new Docker(options);
const vaultPath = (this.app.vault.adapter as any).basePath

// Use Docker-CLI-JS to run the container
try {
await docker.command(`stop brain || true`)
await docker.command(`rm brain || true`)
await docker.command(`run --rm --name brain -v ${vaultPath}:${vaultPath} -e MARKDOWN_FILES=${vaultPath} -e OPENAI_API_KEY=${openaiApiKey} -t lusob04/brain make ingest`);
await docker.command(`stop brain`)
} catch (err) {
console.log('Failed stopping container: ' + err.message);
}
try {
await docker.command(`rm brain`)
} catch (err) {
console.log('Failed removing container: ' + err.message);
}
try {
console.log('Ingesting docs...')
let command = this.settings.useOpenAIEmbeddings ? 'make ingest-openai' : 'make ingest';
let output = await docker.command(`run --rm --name brain -v ${vaultPath}:${vaultPath} -e MARKDOWN_FILES=${vaultPath} -e OPENAI_API_KEY=${openaiApiKey} -t lusob04/brain ${command}`);
console.log('Ingest output: ' + JSON.stringify(output))
} catch (err) {
console.log('Failed ingesting: ' + err.message);
}
Expand Down Expand Up @@ -242,5 +261,16 @@ class BrainSettingTab extends PluginSettingTab {
this.plugin.settings.openaiApiKey = value;
await this.plugin.saveSettings();
}));

new Setting(containerEl)
.setName('Use OpenAI Embeddings')
.setDesc('Check this if you want to use OpenAI embeddings')
.addToggle((toggle) =>
toggle
.setValue(this.plugin.settings.useOpenAIEmbeddings)
.onChange(async (value) => {
this.plugin.settings.useOpenAIEmbeddings = value;
await this.plugin.saveSettings();
}));
}
}
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "brain",
"name": "brAIn",
"version": "1.0.1",
"version": "1.0.3",
"minAppVersion": "0.15.0",
"description": "This is a brAIn for Obsidian. This plugin implements a ChatGPT retrieval for your obsidian notes.",
"author": "Luis Sobrecueva",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-brain",
"version": "1.0.1",
"version": "1.0.3",
"description": "This is a brAIn for Obsidian (https://obsidian.md)",
"main": "main.js",
"scripts": {
Expand Down
4 changes: 3 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"1.0.0": "0.15.0",
"1.0.1": "0.15.0"
"1.0.1": "0.15.0",
"1.0.2": "0.15.0",
"1.0.3": "0.15.0"
}