Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion examples/server/webui/src/components/ChatScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react';
import {useEffect, useMemo, useRef, useState} from 'react';
import { CallbackGeneratedChunk, useAppContext } from '../utils/app.context';
import ChatMessage from './ChatMessage';
import { CanvasType, Message, PendingMessage } from '../utils/types';
Expand Down Expand Up @@ -81,6 +81,33 @@ export default function ChatScreen() {
replaceMessageAndGenerate,
} = useAppContext();
const [inputMsg, setInputMsg] = useState('');
const inputRef = useRef<HTMLTextAreaElement>(null);

// Accept setText message from a parent window and set inputMsg and extraContext
useEffect(() => {
const handleMessage = (event: MessageEvent) => {
if (event.data?.command === 'setText') {
setInputMsg(event.data?.text);
StorageUtils.setExtraContext(event.data?.context)
inputRef.current?.focus();
}
};

window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, []);

// Add a keydown listener that sends the "escapePressed" message to the parent window
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
window.parent.postMessage({ command: 'escapePressed' }, '*');
}
};

window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);

// keep track of leaf node for rendering
const [currNodeId, setCurrNodeId] = useState<number>(-1);
Expand Down Expand Up @@ -203,6 +230,7 @@ export default function ChatScreen() {
<textarea
className="textarea textarea-bordered w-full"
placeholder="Type a message (Shift+Enter to add a new line)"
ref={inputRef}
value={inputMsg}
onChange={(e) => setInputMsg(e.target.value)}
onKeyDown={(e) => {
Expand Down
5 changes: 5 additions & 0 deletions examples/server/webui/src/utils/app.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ export const AppContextProvider = ({
: [{ role: 'system', content: config.systemMessage } as APIMessage]),
...normalizeMsgsForAPI(currMessages),
];
let extraContext:string = await StorageUtils.getExtraContext()
if (extraContext && extraContext != ""){
// insert extra context just after the systemMessage
messages.splice(config.systemMessage.length === 0 ? 0 : 1, 0, { role: 'user', content:extraContext } as APIMessage)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not be a good idea. Some models ignore system prompt. It should be injected into user message instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this puts the extra context message as a user message just before the other user messages. Is there something wrong?

}
if (config.excludeThoughtOnReq) {
messages = filterThoughtFromMsgs(messages);
}
Expand Down
7 changes: 7 additions & 0 deletions examples/server/webui/src/utils/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const dispatchConversationChange = (convId: string) => {
const db = new Dexie('LlamacppWebui') as Dexie & {
conversations: Table<Conversation>;
messages: Table<Message>;
extraContext: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be stored in app.context.tsx instead of here. The DB class is meant to store permanent data.

Also, you only define the type here, not the initial value. extraContext can de undefined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extraContext is in some sense permanent as it is reused in each request to llama.cpp server. However, you are right - it is better to move it in app.context.

};

// https://dexie.org/docs/Version/Version.stores()
Expand Down Expand Up @@ -116,6 +117,12 @@ const StorageUtils = {
});
return conv;
},
async setExtraContext(extraContext: string): Promise<void> {
db.extraContext = extraContext
},
async getExtraContext(): Promise<string> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either define a default value, or explicitly tell that it is undefine-able:

Suggested change
async getExtraContext(): Promise<string> {
async getExtraContext(): Promise<string | undefined> {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As extraContext will be moved in app.context, this function will be removed.

return db.extraContext;
},
/**
* if convId does not exist, throw an error
*/
Expand Down