Skip to content

Commit

Permalink
feat(kb): Link KB to chat
Browse files Browse the repository at this point in the history
  • Loading branch information
RezaRahemtola committed Aug 6, 2024
1 parent 167f7b9 commit 4eb1a8e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/components/ChatsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function saveChatSettings(newChat: Chat) {
username: newChat.username,
modelId: newChat.modelId,
persona: JSON.parse(JSON.stringify(newChat.persona)),
knowledgeBases: JSON.parse(JSON.stringify(newChat.knowledgeBases)),
});
router.go(0);
}
Expand Down
11 changes: 11 additions & 0 deletions src/components/dialog/ChatSettingsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
<model-selector :selected-model="selectedModel" @select-model="(model: UIModel) => (selectedModel = model)" />
</div>
</q-card-section>

<q-card-section>
<div class="tw-gap-2 tw-flex tw-flex-col tw-text-center">
<p>Knowledge bases</p>
<knowledge-bases-selector v-model="selectedKnowledgeBases" />
</div>
</q-card-section>
</ltai-dialog>
</template>

Expand All @@ -43,6 +50,7 @@ import { UIPersona } from 'src/types/personas';
import PersonaDropdown from 'components/select/PersonaSelector.vue';
import { usePersonasStore } from 'stores/personas';
import LtaiDialog from 'components/libertai/LtaiDialog.vue';
import KnowledgeBasesSelector from 'components/select/KnowledgeBasesSelector.vue';
const { avatar } = useSettingsStore();
const personasStore = usePersonasStore();
Expand All @@ -55,6 +63,7 @@ const emit = defineEmits<{ saveChat: [value: Chat] }>();
const username = ref('');
const selectedPersona = ref<UIPersona>(personasStore.personas[0]);
const selectedModel = ref<UIModel>(modelsStore.models[0]);
const selectedKnowledgeBases = ref<string[]>([]);
watch(
() => props.chat,
Expand All @@ -65,6 +74,7 @@ watch(
username.value = newChat.username;
selectedPersona.value = JSON.parse(JSON.stringify(newChat.persona));
selectedKnowledgeBases.value = JSON.parse(JSON.stringify(newChat.knowledgeBases));
const model = modelsStore.models.find((m) => m.id === newChat.modelId);
if (model !== undefined) {
Expand All @@ -79,6 +89,7 @@ const saveSettings = () => {
username: username.value,
modelId: selectedModel.value.id,
persona: selectedPersona.value,
knowledgeBases: selectedKnowledgeBases.value,
});
};
</script>
27 changes: 27 additions & 0 deletions src/components/select/KnowledgeBasesSelector.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<q-select
v-model="selectedKnowledgeBases"
:disable="!knowledgeStore.isLoaded"
:option-label="
(option: KnowledgeBase | string) =>
typeof option === 'string'
? (knowledgeStore.knowledgeBases.find((kb) => kb.id === option)?.name ?? 'Not found')
: option.name
"
:option-value="(option: KnowledgeBase | string) => (typeof option === 'string' ? option : option.id)"
:options="knowledgeStore.knowledgeBases"
emit-value
filled
multiple
use-chips
/>
</template>

<script lang="ts" setup>
import { useKnowledgeStore } from 'stores/knowledge';
import { KnowledgeBase } from 'src/types/knowledge';
const knowledgeStore = useKnowledgeStore();
const selectedKnowledgeBases = defineModel<string[]>();
</script>
15 changes: 12 additions & 3 deletions src/pages/NewChat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
<span>Your name</span>
<q-input v-model="username" bg-color="secondary" input-class="text-light q-px-sm" outlined></q-input>
</q-card-section>

<q-card-section>
<span>Knowledge bases</span>
<knowledge-bases-selector v-model="selectedKnowledgeBases" />
</q-card-section>
</q-card>
</div>
<div class="fixed-bottom absolute q-mb-xl tw-pb-1">
Expand Down Expand Up @@ -65,6 +70,7 @@ import ModelSelector from 'components/select/ModelSelector.vue';
import { UIModel } from 'src/utils/models';
import { UIPersona } from 'src/types/personas';
import { SendMessageParams } from 'src/types/chats';
import KnowledgeBasesSelector from 'components/select/KnowledgeBasesSelector.vue';
const router = useRouter();
Expand All @@ -76,10 +82,11 @@ const settingsStore = useSettingsStore();
const route = useRoute();
// Inputs
// Form values
const selectedModel = ref<UIModel>(modelsStore.models[0]);
const selectedPersona = ref<UIPersona>(personasStore.personas[0]);
const username = ref(settingsStore.username);
const selectedKnowledgeBases = ref<string[]>([]);
watch(
() => route.query.persona as string | undefined,
Expand All @@ -102,10 +109,12 @@ async function sendMessage({ content, attachments }: SendMessageParams) {
// NOTE: this is a ref to the store, so we need to deep clone it
const persona = JSON.parse(JSON.stringify(selectedPersona.value));
const knowledgeBaseIds = JSON.parse(JSON.stringify(selectedKnowledgeBases.value));
// Creates the new chat
const chat = await chatsStore.createChat(title, username.value, selectedModel.value.id, persona);
const chat = chatsStore.createChat(title, username.value, selectedModel.value.id, persona, knowledgeBaseIds);
// Append the first user message to the chat history
await chatsStore.appendUserMessage(chat.id, content, attachments);
chatsStore.appendUserMessage(chat.id, content, attachments);
// Navigate to the chat page
await router.push({ name: 'chat', params: { id: chat.id } });
Expand Down
4 changes: 2 additions & 2 deletions src/stores/chats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const useChatsStore = defineStore(CHATS_STORE_PINIA_KEY, {
}
},

createChat(title: string, username: string, modelId: string, persona: UIPersona): Chat {
createChat(title: string, username: string, modelId: string, persona: UIPersona, knowledgeBaseIds: string[]): Chat {
const id = uuidv4();
const chat: Chat = {
id,
Expand All @@ -90,7 +90,7 @@ export const useChatsStore = defineStore(CHATS_STORE_PINIA_KEY, {
persona,
messages: [],
createdAt: new Date().toISOString(),
knowledgeBases: [],
knowledgeBases: knowledgeBaseIds,
};
this.chats.push(chat);
return chat;
Expand Down
25 changes: 19 additions & 6 deletions src/utils/aleph-persistent-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const SECURITY_AGGREGATE_KEY = 'security';
const MESSAGE = 'LibertAI';
const LIBERTAI_CHANNEL = 'libertai-chat-ui';
const LIBERTAI_SETTINGS_KEY = `${LIBERTAI_CHANNEL}-settings`;
const LIBERTAI_KNOWLEDGE_BASE_IDENTIFIERS_KEY = `${LIBERTAI_CHANNEL}-knowledge-base-identifiers-test-4`;
const LIBERTAI_KNOWLEDGE_BASE_POST_TYPE = `${LIBERTAI_CHANNEL}-knowledge-base-test-4`;
const LIBERTAI_KNOWLEDGE_BASE_IDENTIFIERS_KEY = `${LIBERTAI_CHANNEL}-knowledge-base-identifiers-test-12`;
const LIBERTAI_KNOWLEDGE_BASE_POST_TYPE = `${LIBERTAI_CHANNEL}-knowledge-base-test-12`;
const BUFFER_ENCODING: BufferEncoding = 'hex';

export class AlephPersistentStorage {
Expand Down Expand Up @@ -206,16 +206,29 @@ export class AlephPersistentStorage {
channel: LIBERTAI_CHANNEL,
});

const identifier = {
const identifier: KnowledgeBaseIdentifier = {
id: kb.id,
encryption: {
key: eciesEncrypt(this.encryptionPrivateKey.publicKey.toHex(), key).toString(BUFFER_ENCODING),
iv: eciesEncrypt(this.encryptionPrivateKey.publicKey.toHex(), iv).toString(BUFFER_ENCODING),
key: key.toString(),
iv: iv.toString(),
},
post_hash: response.item_hash,
};

const newKbIdentifiers: KnowledgeBaseIdentifier[] = [...currentKbIdentifiers, identifier];
const newKbIdentifiers: KnowledgeBaseIdentifier[] = [...currentKbIdentifiers, identifier].map((kbIdentifier) => ({
...kbIdentifier,
encryption: {
key: eciesEncrypt(
this.encryptionPrivateKey.publicKey.toHex(),
Buffer.from(kbIdentifier.encryption.key),
).toString(BUFFER_ENCODING),
iv: eciesEncrypt(
this.encryptionPrivateKey.publicKey.toHex(),
Buffer.from(kbIdentifier.encryption.iv),
).toString(BUFFER_ENCODING),
},
}));

await this.subAccountClient.createAggregate({
key: LIBERTAI_KNOWLEDGE_BASE_IDENTIFIERS_KEY,
content: {
Expand Down

0 comments on commit 4eb1a8e

Please sign in to comment.