improve docs

This commit is contained in:
nemo 2024-08-15 12:53:46 +01:00
parent ee52b27017
commit c0037b56e7
5 changed files with 49 additions and 5 deletions

2
auto-imports.d.ts vendored
View File

@ -4,5 +4,5 @@
// Generated by unplugin-auto-import
export {}
declare global {
const ElNotification: typeof import('element-plus/es')['ElNotification']
}

View File

@ -28,7 +28,6 @@
import { Controller, Session, Req, Res, Post } from 'routing-controllers'
import { Request, Response } from 'express'
import OBPClientService from '../services/OBPClientService'
import OauthInjectedService from '../services/OauthInjectedService'
import { Service } from 'typedi'
import * as fs from 'fs'
import * as jwt from 'jsonwebtoken'
@ -39,11 +38,11 @@ import * as jwt from 'jsonwebtoken'
* Controller class for handling Opey related operations.
* This used to hold the /chat endpoint, but that endpoint has become obsolete since using websockets.
* Now it serves to get tokens to authenticate the user at websocket handshake.
* This is called from the frontend when ChatWidget.vue is mounted. (It is done at the backend to keep the private key secret)
*/
export class OpeyController {
constructor(
private obpClientService: OBPClientService,
private oauthInjectedService: OauthInjectedService
) {}
@Post('/token')

View File

@ -51,7 +51,16 @@
export default {
setup() {
/**
* Pinia stores only work properly in the vue composition API, hence the setup() call here, which allows us to use the vue composition API within the vue options API
* See https://vueschool.io/articles/vuejs-tutorials/options-api-vs-composition-api/
* and https://vuejs.org/api/composition-api-setup.html
* */
// We use a pinia store to store the chat messages, and status data like if there is a message stream currently happening or an error state.
const chatStore = useChatStore();
// The connection store merely handles connection to the websocket, and connection status
const connectionStore = useConnectionStore();
socket.off()
@ -88,6 +97,9 @@
}
});
},
/**
* checks the log in status of the user on mount
*/
async checkLoginStatus() {
const currentUser = await getCurrentUser()
const currentResponseKeys = Object.keys(currentUser)
@ -112,8 +124,6 @@
console.log(error)
token = ''
}
socket.auth = { token };
// Establish the WebSocket connection
console.log('Establishing WebSocket connection');
@ -122,7 +132,10 @@
},
async sendMessage() {
if (this.userInput.trim()) {
// Message in OpenAI standard format for user message
const newMessage = { role: 'user', content: this.userInput };
// Push message to pinia store
this.chatMessages.push(newMessage);
this.userInput = '';
this.isLoading = true;
@ -148,6 +161,12 @@
});
}
},
/**
* This function highlights code blocks in the chat messages
*
* @param content
* @param language
*/
highlightCode(content, language) {
if (Prism.languages[language]) {
return Prism.highlight(content, Prism.languages[language], language);
@ -179,6 +198,7 @@
const messages = this.$refs.messages;
messages.scrollTop = messages.scrollHeight;
},
// Following three functions resize the chat widget window
initResize(event) {
this.isResizing = true;
this.startX = event.clientX;
@ -398,6 +418,8 @@
height: 470px;
min-width: 390px;
min-height: 470px;
max-width: 90vw;
max-height: 90vh;
border: 1px solid #ccc;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);

View File

@ -28,26 +28,36 @@
import { defineStore } from 'pinia'
import { socket } from '@/socket'
/**
* Represents a Pinia store for managing chat messages and chatbot responses.
*/
export const useChatStore = defineStore('chat', {
state: () => ({
// Messages a list of messages in the OpenAI format
chatMessages: [] as {role: string; content: string}[],
// Tells us wether a response from the chatbot is currently being streamed or not
isStreaming: false,
// The partial message at a particular moment in time
currentMessageSnapshot: "" as string,
lastError: "" as string,
waitingForResponse: false,
}),
actions: {
bindEvents() {
// TODO: Maybe we don't need to log this except for DEBUG, keep same for now
socket.on("connect", () => {
console.log("Connected to chatbot");
})
// When the assistant stream response starts, we set isStreaming to true
socket.on('response stream start', (response) => {
this.isStreaming = true;
this.waitingForResponse = true;
// We create a temporary blank assistant message for the ChatWidget to render and add text deltas to when they come in
this.chatMessages.push({ role: 'assistant', content: " "})
});
// Text deltas received from the assistant stream (they are like little snippets of the generated response)
socket.on('response stream delta', (response) => {
this.currentMessageSnapshot += response.assistant;
});

View File

@ -28,12 +28,20 @@
import { defineStore } from "pinia";
import { socket } from "@/socket";
/**
* Creates a connection store using Pinia's defineStore function.
* The connection store manages the connection status and provides actions to connect and bind websocket events.
*/
export const useConnectionStore = defineStore("connection", {
state: () => ({
isConnected: false,
}),
actions: {
/**
* Binds events to the socket connection.
* Updates the `isConnected` state when the socket connects or disconnects.
*/
bindEvents() {
socket.on("connect", () => {
this.isConnected = true;
@ -44,6 +52,11 @@ export const useConnectionStore = defineStore("connection", {
});
},
/**
* Connects to the server using the provided token.
* Sets the `auth` property of the socket and connects to the server.
* @param token - The authentication token. I.e. a JWT
*/
connect(token: string) {
socket.auth = { token };
socket.connect();