Skip to content

Commit 3645e1b

Browse files
author
igardev
committed
Webui: Enable communication with parent html (if webui is in iframe):
- Listens for "setText" command from parent with "text" and "context" fields. "text" is set in inputMsg, "context" is used as hidden context on the following requests to the llama.cpp server - On pressing na Escape button sends command "escapePressed" to the parent Example handling from the parent html side: - Send command "setText" from parent html to webui in iframe: const iframe = document.getElementById('askAiIframe'); if (iframe) { iframe.contentWindow.postMessage({ command: 'setText', text: text, context: context }, '*'); } - Listen for Escape key from webui on parent html: // Listen for escape key event in the iframe window.addEventListener('keydown', (event) => { if (event.key === 'Escape') { // Process case when Escape is pressed inside webui } });
1 parent 73e2ed3 commit 3645e1b

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

examples/server/webui/src/components/ChatScreen.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useMemo, useState } from 'react';
1+
import {useEffect, useMemo, useRef, useState} from 'react';
22
import { CallbackGeneratedChunk, useAppContext } from '../utils/app.context';
33
import ChatMessage from './ChatMessage';
44
import { CanvasType, Message, PendingMessage } from '../utils/types';
@@ -81,6 +81,33 @@ export default function ChatScreen() {
8181
replaceMessageAndGenerate,
8282
} = useAppContext();
8383
const [inputMsg, setInputMsg] = useState('');
84+
const inputRef = useRef<HTMLTextAreaElement>(null);
85+
86+
// Accept setText message from a parent window and set inputMsg and extraContext
87+
useEffect(() => {
88+
const handleMessage = (event: MessageEvent) => {
89+
if (event.data?.command === 'setText') {
90+
setInputMsg(event.data?.text);
91+
StorageUtils.setExtraContext(event.data?.context)
92+
inputRef.current?.focus();
93+
}
94+
};
95+
96+
window.addEventListener('message', handleMessage);
97+
return () => window.removeEventListener('message', handleMessage);
98+
}, []);
99+
100+
// Add a keydown listener that sends the "escapePressed" message to the parent window
101+
useEffect(() => {
102+
const handleKeyDown = (event: KeyboardEvent) => {
103+
if (event.key === 'Escape') {
104+
window.parent.postMessage({ command: 'escapePressed' }, '*');
105+
}
106+
};
107+
108+
window.addEventListener('keydown', handleKeyDown);
109+
return () => window.removeEventListener('keydown', handleKeyDown);
110+
}, []);
84111

85112
// keep track of leaf node for rendering
86113
const [currNodeId, setCurrNodeId] = useState<number>(-1);
@@ -203,6 +230,7 @@ export default function ChatScreen() {
203230
<textarea
204231
className="textarea textarea-bordered w-full"
205232
placeholder="Type a message (Shift+Enter to add a new line)"
233+
ref={inputRef}
206234
value={inputMsg}
207235
onChange={(e) => setInputMsg(e.target.value)}
208236
onKeyDown={(e) => {

examples/server/webui/src/utils/app.context.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ export const AppContextProvider = ({
174174
: [{ role: 'system', content: config.systemMessage } as APIMessage]),
175175
...normalizeMsgsForAPI(currMessages),
176176
];
177+
let extraContext:string = await StorageUtils.getExtraContext()
178+
if (extraContext && extraContext != ""){
179+
// insert extra context just after the systemMessage
180+
messages.splice(config.systemMessage.length === 0 ? 0 : 1, 0, { role: 'user', content:extraContext } as APIMessage)
181+
}
177182
if (config.excludeThoughtOnReq) {
178183
messages = filterThoughtFromMsgs(messages);
179184
}

examples/server/webui/src/utils/storage.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const dispatchConversationChange = (convId: string) => {
2121
const db = new Dexie('LlamacppWebui') as Dexie & {
2222
conversations: Table<Conversation>;
2323
messages: Table<Message>;
24+
extraContext: string;
2425
};
2526

2627
// https://dexie.org/docs/Version/Version.stores()
@@ -116,6 +117,12 @@ const StorageUtils = {
116117
});
117118
return conv;
118119
},
120+
async setExtraContext(extraContext: string): Promise<void> {
121+
db.extraContext = extraContext
122+
},
123+
async getExtraContext(): Promise<string> {
124+
return db.extraContext;
125+
},
119126
/**
120127
* if convId does not exist, throw an error
121128
*/

0 commit comments

Comments
 (0)