Skip to content

Commit

Permalink
Merge pull request #60 from your-papa/dev
Browse files Browse the repository at this point in the history
Release 0.6.0
  • Loading branch information
nicobrauchtgit authored Mar 29, 2024
2 parents 789cc27 + ba78f27 commit 425b66b
Show file tree
Hide file tree
Showing 15 changed files with 317 additions and 80 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Interact with your privacy focused assistant, leveraging Ollama or OpenAI, making your second brain even smarter.",
"author": "Leo310, nicobrauchtgit",
"authorUrl": "https://github.com/nicobrauchtgit",
"version": "0.5.1",
"version": "0.6.0",
"minAppVersion": "1.5.0",
"isDesktopOnly": true
}
19 changes: 10 additions & 9 deletions src/components/Chat/QuickSettingsDrawer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import LoadingAnimation from '../base/LoadingAnimation.svelte';
import { ConfirmModal } from '../Settings/ConfirmModal';
import { get } from 'svelte/store';
import Ollama from '../Settings/Ollama.svelte';
const icon = (node: HTMLElement, iconId: string) => {
setIcon(node, iconId);
Expand Down Expand Up @@ -51,13 +52,13 @@
}
const languages: { display: Language; value: Language }[] = Object.values(Languages).map((language: Language) => ({ display: language, value: language }));
const setAssistantLanguage = (selected: Language) => {
$data.assistantLanguage = selected;
$data.initialAssistantMessageContent = Prompts[selected].initialAssistantMessage;
if ($chatHistory.length === 1) {
chatHistory.reset;
$plugin.saveSettings();
}
if ($chatHistory.length === 1) chatHistory.reset();
$plugin.saveSettings();
};
function setChatViewDensity() {
$data.isChatComfy = !$data.isChatComfy;
Expand Down Expand Up @@ -99,7 +100,7 @@
aria-label={$t('quick_settings.initialize')}
on:click={() => $plugin.s2b.init()}
class="h-8 rounded-l-md px-4 py-2 transition duration-300 ease-in-out hover:bg-[--text-accent-hover]"
use:icon={'play'}
use:icon={'power'}
/>
{:else if $papaState === 'loading'}
<LoadingAnimation />
Expand Down Expand Up @@ -136,10 +137,10 @@
</div>
{:else if $papaState === 'error'}
{#if $errorState === 'ollama-gen-model-not-installed'}
<h3 class="text-center text-primary">{$t('install_model', { values: { model: $data.ollamaGenModel.model } })}</h3>
<PullOllamaModel pullModel={$data.ollamaEmbedModel.model} onSuccessfulPull={() => ($papaState = 'settings-change')} />
{:else if $errorState === 'ollama-embed-model-not-installed'}}
<h3 class="text-center text-primary">{$t('install_model', { values: { model: $data.ollamaEmbedModel.model } })}</h3>
<h3 class="text-center text-primary">{$t('quick_settings.error.install_model', { values: { model: $data.ollamaGenModel.model } })}</h3>
<PullOllamaModel pullModel={$data.ollamaGenModel.model} onSuccessfulPull={() => ($papaState = 'settings-change')} />
{:else if $errorState === 'ollama-embed-model-not-installed'}
<h3 class="text-center text-primary">{$t('quick_settings.error.install_model', { values: { model: $data.ollamaEmbedModel.model } })}</h3>
<PullOllamaModel pullModel={$data.ollamaEmbedModel.model} onSuccessfulPull={() => ($papaState = 'settings-change')} />
{:else if $errorState === 'failed-indexing'}
<h3 class="text-center">{$t('notice.failed_indexing')}</h3>
Expand Down
80 changes: 80 additions & 0 deletions src/components/Modal/PullModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<script lang="ts">
import { onMount } from 'svelte';
import { isOllamaRunning } from '../../controller/Ollama';
import PullOllamaModel from '../Onboarding/PullOllamaModel.svelte';
import SettingContainer from '../Settings/SettingContainer.svelte';
import { t } from 'svelte-i18n';
import { data } from '../../store';
import { OllamaGenModelNames, OllamaEmbedModelNames } from '../Settings/models';
import { getOllamaModels, ollamaGenChange, ollamaEmbedChange } from '../../controller/Ollama';
import type { PullModal } from './PullModal';
import DotAnimation from '../base/DotAnimation.svelte';
export let modal: PullModal;
let model = '';
let isOllama: boolean;
let pulledModel = false;
let installedOllamaModels: string[] = [];
onMount(async () => {
installedOllamaModels = await getOllamaModels();
isOllama = await isOllamaRunning();
});
</script>

<div class="modal-title">{$t('cmd.pull_model')}</div>
<div class="modal-content">
{#if !isOllama}
Ollama is Not Running
{:else if isOllama === undefined}
Loading
<DotAnimation />
{:else}
<PullOllamaModel
text={$t('modal.pull_model_name')}
desc={$t('modal.pull_model_desc')}
onSuccessfulPull={async () => {
installedOllamaModels = await getOllamaModels();
pulledModel = true;
}}
/>
{#if pulledModel}
<SettingContainer
name={$t('settings.ollama.gen_model')}
desc={$t('settings.ollama.model_descriptions.' + $data.ollamaGenModel.model, { default: '' })}
>
<select class="dropdown" bind:value={$data.ollamaGenModel.model} on:change={() => ollamaGenChange($data.ollamaGenModel.model)}>
<optgroup label={$t('settings.ollama.recommended')}>
{#each OllamaGenModelNames as model}
<option value={model}>{model}</option>
{/each}
</optgroup>
<optgroup label={$t('settings.ollama.other')}>
{#each installedOllamaModels.filter((model) => !OllamaGenModelNames.includes(model) && !OllamaEmbedModelNames.includes(model)) as model}
<option value={model}>{model}</option>
{/each}
</optgroup>
</select>
</SettingContainer>
<!-- Ollama Embed Model -->
<SettingContainer
name={$t('settings.ollama.embed_model')}
desc={$t('settings.ollama.model_descriptions.' + $data.ollamaEmbedModel.model, { default: '' })}
>
<select class="dropdown" bind:value={$data.ollamaEmbedModel.model} on:change={() => ollamaEmbedChange($data.ollamaEmbedModel.model)}>
<optgroup label={$t('settings.ollama.recommended')}>
{#each OllamaEmbedModelNames as model}
<option value={model}>{model}</option>
{/each}
</optgroup>
<optgroup label={$t('settings.ollama.other')}>
{#each installedOllamaModels.filter((model) => !OllamaEmbedModelNames.includes(model)) as model}
<option value={model}>{model}</option>
{/each}
</optgroup>
</select>
</SettingContainer>
{/if}
{/if}
</div>
23 changes: 23 additions & 0 deletions src/components/Modal/PullModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Modal, App } from 'obsidian';
import PullComponent from './PullModal.svelte';

export class PullModal extends Modal {
component: PullComponent;
constructor(app: App) {
super(app);
}

onOpen() {
new PullComponent({
target: this.contentEl,
props: {
modal: this,
},
});
}

onClose() {
const { contentEl } = this;
contentEl.empty();
}
}
51 changes: 51 additions & 0 deletions src/components/Modal/RemoveModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script lang="ts">
import { onMount } from 'svelte';
import { deleteOllamaModels, isOllamaRunning } from '../../controller/Ollama';
import { t } from 'svelte-i18n';
import { getOllamaModels } from '../../controller/Ollama';
import type { PullModal } from './PullModal';
import DropdownComponent from '../base/Dropdown.svelte';
import DotAnimation from '../base/DotAnimation.svelte';
export let modal: PullModal;
let model = '';
let isOllama: boolean;
let installedOllamaModels: string[] = [];
onMount(async () => {
installedOllamaModels = await getOllamaModels();
isOllama = await isOllamaRunning();
});
</script>

<div class="modal-title">{$t('cmd.remove_model')}</div>
<div class="modal-content">
{#if isOllama === false}
Ollama is Not Running
{:else if isOllama === undefined}
Loading
<DotAnimation />
{:else}
<div class="mb-1 flex items-center justify-between">
<div>
<div class="setting-item-name">{$t('modal.remove.name')}</div>
<div class="setting-item-description">{$t('modal.remove.desc')}</div>
</div>
<div class="flex flex-row justify-end gap-2">
<DropdownComponent
options={installedOllamaModels.map((model) => ({ display: model, value: model }))}
selected={model}
changeFunc={(e) => (model = e)}
/>
<button
class="mod-warning"
on:click={async () => {
await deleteOllamaModels(model);
installedOllamaModels = await getOllamaModels();
}}>{$t('general.delete')}</button
>
</div>
</div>
{/if}
</div>
23 changes: 23 additions & 0 deletions src/components/Modal/RemoveModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Modal, App } from 'obsidian';
import RemoveComponent from './RemoveModal.svelte';

export class RemoveModal extends Modal {
component: RemoveComponent;
constructor(app: App) {
super(app);
}

onOpen() {
new RemoveComponent({
target: this.contentEl,
props: {
modal: this,
},
});
}

onClose() {
const { contentEl } = this;
contentEl.empty();
}
}
6 changes: 1 addition & 5 deletions src/components/Onboarding/OllamaSetup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@
{#if isOrigin}
<li>
{$t('onboarding.ollama.install_model')}<br />
<div class="flex flex-wrap items-center justify-between">
{$t('onboarding.ollama.recommended_models')}
<input type="text" list="ollama-models" bind:value={pullModel} />
</div>
<PullOllamaModel {pullModel} onSuccessfulPull={async () => (ollamaModels = await getOllamaModels())} />
<PullOllamaModel {pullModel} text="Recommended" onSuccessfulPull={async () => (ollamaModels = await getOllamaModels())} />
</li>
{#if ollamaModels.length > 0}
<li>
Expand Down
46 changes: 27 additions & 19 deletions src/components/Onboarding/PullOllamaModel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
import { t } from 'svelte-i18n';
import ProgressBar from '../base/ProgressBar.svelte';
import { cancelPullModel } from '../../store';
import InputComponent from '../base/Text.svelte';
import DotAnimation from '../base/DotAnimation.svelte';
export let onSuccessfulPull: () => void = () => {};
export let pullModel: string;
export let text = '';
export let desc = '';
export let pullModel: string = '';
let isPullingModel = false;
let total: number = 0;
let progress: number = 0;
let status: string = '';
let isPullingError = false;
console.log('pullModel', pullModel);
async function pullOllamaModelStream() {
isPullingModel = true;
Expand Down Expand Up @@ -44,37 +49,40 @@
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
let index = 0;
$: if (isPullingModel) {
setTimeout(() => {
index = (index + 1) % 4;
}, 300);
}
</script>

{#if !isPullingModel}
<button on:click={() => pullOllamaModelStream()}>Install</button>
{:else}
<div class="flex w-full justify-between">
<div class="mb-1 flex items-center justify-between">
<div>
{status}
{#each ['', '.', '..', '...'] as sequence, i}
{#if i === index}
{sequence}
{/if}
{/each}
<div class="setting-item-name">{text}</div>
<div class="setting-item-description">{desc}</div>
</div>
<div class="flex flex-row justify-end gap-2">
<InputComponent styles="w-4/6" value={pullModel} changeFunc={(v) => (pullModel = v)} />
<button on:click={() => pullOllamaModelStream()}>{$t('general.install')}</button>
</div>
</div>
{:else}
<div class="flex w-full items-center gap-2">
<div class="flex w-full flex-col">
<div class="flex w-full justify-between">
<div>
{status}
<DotAnimation />
</div>
{progress}% / {formatBytes(total)}
</div>
<ProgressBar {progress} />
</div>
{progress}% / {formatBytes(total)}
<button
use:icon={'x'}
aria-label={$t('pullModel.cancel')}
on:click={() => {
$cancelPullModel = true;
}}
class="h-8 rounded-l-md px-4 py-2 transition duration-300 ease-in-out hover:bg-[--text-accent-hover]"
class="mb-1 h-8 rounded-l-md px-4 py-2 transition duration-300 ease-in-out hover:bg-[--text-accent-hover]"
/>
</div>
<ProgressBar {progress} />
{/if}
{#if isPullingError}
<p>There was an error pulling the recommended model</p>
Expand Down
23 changes: 1 addition & 22 deletions src/components/Settings/Ollama.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import TextComponent from '../base/Text.svelte';
import SettingContainer from './SettingContainer.svelte';
import ButtonComponent from '../base/Button.svelte';
import { changeOllamaBaseUrl, getOllamaModels, isOllamaRunning } from '../../controller/Ollama';
import { changeOllamaBaseUrl, getOllamaModels, isOllamaRunning, ollamaEmbedChange, ollamaGenChange } from '../../controller/Ollama';
import { OllamaGenModelNames, OllamaGenModels, OllamaEmbedModelNames } from './models';
import { onMount } from 'svelte';
Expand All @@ -29,27 +29,6 @@
isRunning = await isOllamaRunning();
styleOllamaBaseUrl = isRunning ? '' : '!border-[--background-modifier-error]';
};
const ollamaGenChange = (selected: string) => {
$data.ollamaGenModel.model = selected;
$data.ollamaGenModel.contextWindow = OllamaGenModels[selected] ? OllamaGenModels[selected].contextWindow : 2048;
$plugin.saveSettings();
if (!installedOllamaModels.includes(selected)) {
papaState.set('error');
errorState.set('ollama-gen-model-not-installed');
return;
}
$plugin.s2b.setGenModel($data.openAIGenModel);
};
const ollamaEmbedChange = (selected: string) => {
$data.ollamaEmbedModel.model = selected;
$plugin.saveSettings();
if (!installedOllamaModels.includes(selected)) {
papaState.set('error');
errorState.set('ollama-embed-model-not-installed');
return;
}
papaState.set('settings-change');
};
</script>

<SettingContainer name="Ollama" isHeading={true} desc={$t('settings.ollama.desc')}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Settings/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ export const OllamaGenModels = {
export const OpenAIGenModelNames = Object.keys(OpenAIGenModels);
export const OllamaGenModelNames = Object.keys(OllamaGenModels);
export const OpenAIEmbedModelNames = ['text-embedding-3-large', 'text-embedding-3-small', 'text-embedding-ada-002'];
export const OllamaEmbedModelNames = ['nomic-embed-text'];
export const OllamaEmbedModelNames = ['nomic-embed-text', 'mxbai-embed-large'];
Loading

0 comments on commit 425b66b

Please sign in to comment.