|
@@ -1,10 +1,11 @@
|
|
|
-import { useEffect, useMemo, useState } from 'react';
|
|
|
|
|
|
|
+import { useEffect, useMemo, useRef, useState } from 'react';
|
|
|
import { CallbackGeneratedChunk, useAppContext } from '../utils/app.context';
|
|
import { CallbackGeneratedChunk, useAppContext } from '../utils/app.context';
|
|
|
import ChatMessage from './ChatMessage';
|
|
import ChatMessage from './ChatMessage';
|
|
|
import { CanvasType, Message, PendingMessage } from '../utils/types';
|
|
import { CanvasType, Message, PendingMessage } from '../utils/types';
|
|
|
import { classNames, throttle } from '../utils/misc';
|
|
import { classNames, throttle } from '../utils/misc';
|
|
|
import CanvasPyInterpreter from './CanvasPyInterpreter';
|
|
import CanvasPyInterpreter from './CanvasPyInterpreter';
|
|
|
import StorageUtils from '../utils/storage';
|
|
import StorageUtils from '../utils/storage';
|
|
|
|
|
+import { useVSCodeContext } from '../utils/llama-vscode';
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* A message display is a message node with additional information for rendering.
|
|
* A message display is a message node with additional information for rendering.
|
|
@@ -81,6 +82,14 @@ export default function ChatScreen() {
|
|
|
replaceMessageAndGenerate,
|
|
replaceMessageAndGenerate,
|
|
|
} = useAppContext();
|
|
} = useAppContext();
|
|
|
const [inputMsg, setInputMsg] = useState('');
|
|
const [inputMsg, setInputMsg] = useState('');
|
|
|
|
|
+ const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
|
|
|
+
|
|
|
|
|
+ const { extraContext, clearExtraContext } = useVSCodeContext(
|
|
|
|
|
+ inputRef,
|
|
|
|
|
+ setInputMsg
|
|
|
|
|
+ );
|
|
|
|
|
+ // TODO: improve this when we have "upload file" feature
|
|
|
|
|
+ const currExtra: Message['extra'] = extraContext ? [extraContext] : undefined;
|
|
|
|
|
|
|
|
// keep track of leaf node for rendering
|
|
// keep track of leaf node for rendering
|
|
|
const [currNodeId, setCurrNodeId] = useState<number>(-1);
|
|
const [currNodeId, setCurrNodeId] = useState<number>(-1);
|
|
@@ -115,10 +124,20 @@ export default function ChatScreen() {
|
|
|
setCurrNodeId(-1);
|
|
setCurrNodeId(-1);
|
|
|
// get the last message node
|
|
// get the last message node
|
|
|
const lastMsgNodeId = messages.at(-1)?.msg.id ?? null;
|
|
const lastMsgNodeId = messages.at(-1)?.msg.id ?? null;
|
|
|
- if (!(await sendMessage(currConvId, lastMsgNodeId, inputMsg, onChunk))) {
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ !(await sendMessage(
|
|
|
|
|
+ currConvId,
|
|
|
|
|
+ lastMsgNodeId,
|
|
|
|
|
+ inputMsg,
|
|
|
|
|
+ currExtra,
|
|
|
|
|
+ onChunk
|
|
|
|
|
+ ))
|
|
|
|
|
+ ) {
|
|
|
// restore the input message if failed
|
|
// restore the input message if failed
|
|
|
setInputMsg(lastInpMsg);
|
|
setInputMsg(lastInpMsg);
|
|
|
}
|
|
}
|
|
|
|
|
+ // OK
|
|
|
|
|
+ clearExtraContext();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleEditMessage = async (msg: Message, content: string) => {
|
|
const handleEditMessage = async (msg: Message, content: string) => {
|
|
@@ -129,6 +148,7 @@ export default function ChatScreen() {
|
|
|
viewingChat.conv.id,
|
|
viewingChat.conv.id,
|
|
|
msg.parent,
|
|
msg.parent,
|
|
|
content,
|
|
content,
|
|
|
|
|
+ msg.extra,
|
|
|
onChunk
|
|
onChunk
|
|
|
);
|
|
);
|
|
|
setCurrNodeId(-1);
|
|
setCurrNodeId(-1);
|
|
@@ -143,6 +163,7 @@ export default function ChatScreen() {
|
|
|
viewingChat.conv.id,
|
|
viewingChat.conv.id,
|
|
|
msg.parent,
|
|
msg.parent,
|
|
|
null,
|
|
null,
|
|
|
|
|
+ msg.extra,
|
|
|
onChunk
|
|
onChunk
|
|
|
);
|
|
);
|
|
|
setCurrNodeId(-1);
|
|
setCurrNodeId(-1);
|
|
@@ -203,6 +224,7 @@ export default function ChatScreen() {
|
|
|
<textarea
|
|
<textarea
|
|
|
className="textarea textarea-bordered w-full"
|
|
className="textarea textarea-bordered w-full"
|
|
|
placeholder="Type a message (Shift+Enter to add a new line)"
|
|
placeholder="Type a message (Shift+Enter to add a new line)"
|
|
|
|
|
+ ref={inputRef}
|
|
|
value={inputMsg}
|
|
value={inputMsg}
|
|
|
onChange={(e) => setInputMsg(e.target.value)}
|
|
onChange={(e) => setInputMsg(e.target.value)}
|
|
|
onKeyDown={(e) => {
|
|
onKeyDown={(e) => {
|