Skip to content

Commit

Permalink
feat(kb): Setup
Browse files Browse the repository at this point in the history
  • Loading branch information
RezaRahemtola committed Jul 30, 2024
1 parent 3a4eb92 commit 5fe4f6e
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 101 deletions.
5 changes: 5 additions & 0 deletions public/icons/svg/book_lighten.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 0 additions & 12 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
<template>
<router-view />
</template>

<script lang="ts" setup>
import { onMounted } from 'vue';
import { useKnowledgeStore } from 'stores/knowledge';
const knowledgeStore = useKnowledgeStore();
onMounted(() => {
// Set the knowledge store to load when the app is mounted
knowledgeStore.load();
});
</script>
8 changes: 8 additions & 0 deletions src/layouts/MainLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@

<chats-list />

<q-item to="/knowledge-base">
<img :src="`icons/svg/book${$q.dark.mode ? '_lighten' : ''}.svg`" alt="knowledge" />

<q-item-section class="q-pl-sm">
<span>Knowledge base</span>
</q-item-section>
</q-item>

<q-item to="/persona-management">
<img :src="`icons/svg/robot${$q.dark.mode ? '_lighten' : ''}.svg`" alt="persona" />

Expand Down
77 changes: 8 additions & 69 deletions src/pages/KnowledgeBase.vue
Original file line number Diff line number Diff line change
@@ -1,72 +1,11 @@
<template>
<q-layout container style="height: 100vh" view="hHh lpR fff">
<q-header class="bg-primary text-white" elevated>
<q-toolbar class="row justify-between items-center q-px-lg">
<q-btn dense flat icon="home" round @click="$router.push('/')" />
<q-toolbar-title>Knowledge Database</q-toolbar-title>
</q-toolbar>
</q-header>

<q-page-container>
<div class="row justify-center q-pa-md">
<div class="col-lg-8 col-sm-12">
<q-list>
<q-item v-for="document in documents" :key="document.id" clickable @click="onRowClick(document)">
<q-item-section>
<q-item-label>{{ document.title }}</q-item-label>
</q-item-section>
<!-- If the document is selected, show the deletion icon -->
<q-item-section v-if="selectedDocumentId === document.id" side>
<q-btn-group dense flat>
<q-btn icon="delete" @click="removeSelectedDocument" />
<q-tooltip>Remove Document</q-tooltip>
</q-btn-group>
</q-item-section>
</q-item>
</q-list>
</div>
</div>
</q-page-container>
</q-layout>
<section class="max-sm:tw-mx-4 md:tw-mx-10 tw-my-5">
<h4 class="text-h4 text-semibold tw-mb-5">Knowledge base</h4>
<p>Manage your knowledge bases</p>
<div class="tw-my-4 tw-flex md:tw-justify-end">
<q-btn icon="img:icons/svg/add.svg" label="Create knowledge base" no-caps unelevated />
</div>
</section>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { Document } from '@libertai/libertai-js';
import { useKnowledgeStore } from 'stores/knowledge';
const knowledgeStore = useKnowledgeStore();
// Columns for the table displaying documents
// const columns = [
// { name: 'id', label: 'ID', field: 'id' },
// { name: 'title', label: 'Title', field: 'title' },
// ];
// Documents data source
const { documents } = storeToRefs(knowledgeStore);
// Selected document
// const selectedDocument = ref(null);
const selectedDocumentId = ref<string | null>(null);
// Edited document object
// const editedDocument = ref({ title: '', description: '' });
// Form title based on whether we're adding or editing a document
// const formTitle = computed(() => (selectedDocument.value ? 'Edit Document' : 'Add Document'));
// On row click event handler for the table
function onRowClick(row: Document) {
selectedDocumentId.value = row.id;
}
async function removeSelectedDocument() {
if (selectedDocumentId.value) {
await knowledgeStore.removeDocument(selectedDocumentId.value);
selectedDocumentId.value = null;
}
}
</script>
<script lang="ts" setup></script>
3 changes: 1 addition & 2 deletions src/router/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ const routes = [
name: 'tokens-detail',
component: () => import('pages/TokensDetail.vue'),
},
// knowledge db
{
path: 'knowledge-db',
path: 'knowledge-base',
component: () => import('src/pages/KnowledgeBase.vue'),
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/stores/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const useAccountStore = defineStore('account', {
}

this.alephStorage = alephStorage;
const settingsOnAleph = await this.alephStorage.fetch();
const settingsOnAleph = await this.alephStorage.fetchSettings();
const saveOnAleph = !settingsOnAleph;
await settingsStore.update(settingsOnAleph ?? {}, saveOnAleph);
},
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const useSettingsStore = defineStore('settings', {
const account: any = useAccountStore();

if (account.alephStorage !== null) {
await account.alephStorage.save(settings);
await account.alephStorage.saveSettings(settings);
}
},
},
Expand Down
46 changes: 30 additions & 16 deletions src/utils/aleph-persistent-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { signMessage } from '@wagmi/core';
import { config } from 'src/config/wagmi';
import { SignMessageReturnType } from 'viem';

const MESSAGE = 'LibertAI';
const LIBERTAI_KEY = 'libertai-chat-ui';
// Aleph keys and channels
const SECURITY_AGGREGATE_KEY = 'security';
const MESSAGE = 'LibertAI';
const LIBERTAI_CHANNEL = 'libertai-chat-ui';
const LIBERTAI_SETTINGS_KEY = `${LIBERTAI_CHANNEL}-settings`;

export class AlephPersistentStorage {
constructor(
Expand Down Expand Up @@ -48,23 +50,36 @@ export class AlephPersistentStorage {
// TODO: Add zod parsing
const securitySettings = (await accountClient.fetchAggregate(account.address, SECURITY_AGGREGATE_KEY)) as any;

type SecurityAuthorization = {
address: string;
chain?: string;
channels?: string;
types?: string;
post_types?: string;
aggregate_keys?: string;
};

if (
!securitySettings.authorizations.find(
(authorization: any) =>
(authorization: SecurityAuthorization) =>
authorization.address === subAccount.address &&
authorization.types.includes('AGGREGATE') &&
authorization.aggregate_keys.includes(LIBERTAI_KEY),
authorization.types === undefined &&
authorization.channels !== undefined &&
authorization.channels.includes(LIBERTAI_CHANNEL),
)
) {
const oldAuthorizations = securitySettings.authorizations.filter(
(a: SecurityAuthorization) => a.address !== subAccount.address,
);

await accountClient.createAggregate({
key: SECURITY_AGGREGATE_KEY,
content: {
authorizations: [
...securitySettings.authorizations,
...oldAuthorizations,
{
address: subAccount.address,
types: ['AGGREGATE'],
aggregate_keys: [LIBERTAI_KEY],
channels: [LIBERTAI_CHANNEL],
},
],
},
Expand All @@ -78,32 +93,31 @@ export class AlephPersistentStorage {
authorizations: [
{
address: subAccount.address,
types: ['AGGREGATE'],
aggregate_keys: [LIBERTAI_KEY],
channels: [LIBERTAI_CHANNEL],
},
],
},
});
}
}

async save(content: object) {
async saveSettings(content: object) {
try {
const message = await this.subAccountClient.createAggregate({
key: LIBERTAI_KEY,
key: LIBERTAI_SETTINGS_KEY,
content,
address: this.account.address,
channel: LIBERTAI_KEY,
channel: LIBERTAI_CHANNEL,
});
console.log(`Data saved on Aleph with hash ${message.item_hash}`);
} catch (error) {
console.error(`Saving data on Aleph failed: ${error}`);
}
}

async fetch() {
async fetchSettings() {
try {
const settings = await this.subAccountClient.fetchAggregate(this.account.address, LIBERTAI_KEY);
const settings = await this.subAccountClient.fetchAggregate(this.account.address, LIBERTAI_SETTINGS_KEY);
return settings;
} catch (error) {
console.error(`Fetching settings from Aleph failed: ${error}`);
Expand All @@ -115,7 +129,7 @@ export class AlephPersistentStorage {
const message = await this.subAccountClient.createStore({
fileObject: file,
storageEngine: ItemType.ipfs,
channel: LIBERTAI_KEY,
channel: LIBERTAI_CHANNEL,
});
return message;
}
Expand Down

0 comments on commit 5fe4f6e

Please sign in to comment.