1
0
Fork 0
This commit is contained in:
Pabloader 2026-04-08 07:39:57 +00:00
parent f685118da0
commit 446cda6502
1 changed files with 66 additions and 56 deletions

View File

@ -186,8 +186,8 @@ export const ChatPanel = () => {
const content = delta?.content; const content = delta?.content;
if (content) { if (content) {
accumulatedContent += content; accumulatedContent += content;
if (currentWorld?.chatOnly && accumulatedContent.startsWith(prefix)) { if (currentWorld?.chatOnly && accumulatedContent.trimStart().startsWith(prefix)) {
accumulatedContent = accumulatedContent.slice(prefix.length); accumulatedContent = accumulatedContent.trimStart().slice(prefix.length).trimStart();
} }
} }
const reasoningContent = delta?.reasoning_content; const reasoningContent = delta?.reasoning_content;
@ -258,8 +258,44 @@ export const ChatPanel = () => {
} }
}, [currentStory, connection, model]); }, [currentStory, connection, model]);
const handleRegenerate = useCallback(async () => {
if (!currentStory || !connection || !model || isLoading) return;
// Only regenerate if last message is assistant
const lastMessage = currentStory.chatMessages.at(-1);
const isAssistant = lastMessage?.role === 'assistant';
setIsLoading(true);
setError(null);
abortControllerRef.current = new AbortController();
const excludedMessages: string[] = [];
try {
if (isAssistant) {
// Delete the last assistant message and regenerate
dispatch({
type: 'DELETE_CHAT_MESSAGES_FROM',
worldId: currentWorld!.id,
storyId: currentStory.id,
messageId: lastMessage.id,
});
excludedMessages.push(lastMessage.id);
}
await sendMessage([], excludedMessages);
} finally {
setIsLoading(false);
}
}, [currentStory, currentWorld, connection, model, isLoading, sendMessage]);
const handleSendMessage = useCallback(async () => { const handleSendMessage = useCallback(async () => {
if (!currentStory || !input.trim() || !connection || !model || isLoading) return; if (!currentStory || !connection || !model || isLoading) return;
if (!input.trim()) {
if (lastMessage?.role === 'user') {
handleRegenerate();
}
return;
}
setInput(''); setInput('');
setIsLoading(true); setIsLoading(true);
@ -275,7 +311,7 @@ export const ChatPanel = () => {
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
}, [currentStory, input, connection, model, isLoading, sendMessage]); }, [currentStory, input, connection, model, isLoading, sendMessage, handleRegenerate]);
const handleContinue = useCallback(async () => { const handleContinue = useCallback(async () => {
if (!currentStory || !connection || !model || isLoading) return; if (!currentStory || !connection || !model || isLoading) return;
@ -352,32 +388,6 @@ export const ChatPanel = () => {
setEditingContent(''); setEditingContent('');
}, [setEditingContent]); }, [setEditingContent]);
const handleRegenerate = useCallback(async () => {
if (!currentStory || !connection || !model || isLoading) return;
// Only regenerate if last message is assistant
const lastMessage = currentStory.chatMessages.at(-1);
if (!lastMessage || lastMessage.role !== 'assistant') return;
setIsLoading(true);
setError(null);
abortControllerRef.current = new AbortController();
try {
// Delete the last assistant message and regenerate
dispatch({
type: 'DELETE_CHAT_MESSAGES_FROM',
worldId: currentWorld!.id,
storyId: currentStory.id,
messageId: lastMessage.id,
});
await sendMessage([], [lastMessage.id]);
} finally {
setIsLoading(false);
}
}, [currentStory, currentWorld, connection, model, isLoading, dispatch, sendMessage]);
const isDisabled = !currentStory || !connection || !model || isLoading; const isDisabled = !currentStory || !connection || !model || isLoading;
return ( return (
@ -501,9 +511,9 @@ export const ChatPanel = () => {
)} )}
{currentStory && ( {currentStory && (
<div class={styles.inputContainer}> <div class={styles.inputContainer}>
{!currentWorld?.chatOnly && ( <div class={styles.optionsRow}>
<div class={styles.optionsRow}> <label class={styles.toggleContainer}>
<label class={styles.toggleContainer}> {!currentWorld?.chatOnly && (<>
<input <input
type="checkbox" type="checkbox"
checked={enableThinking} checked={enableThinking}
@ -514,19 +524,21 @@ export const ChatPanel = () => {
disabled={isDisabled} disabled={isDisabled}
/> />
<span>Enable thinking</span> <span>Enable thinking</span>
</label> </>)}
<div class={styles.tokenCounter}> </label>
{tokenCount && <span>{tokenCount.taken} / {tokenCount.total} tokens</span>} <div class={styles.tokenCounter}>
<button {tokenCount && <span>{tokenCount.taken} / {tokenCount.total} tokens</span>}
class={styles.summarizeButton}
onClick={summarizeAll} {!currentWorld?.chatOnly && (<button
disabled={isSummarizing || !currentStory || !connection || !model} class={styles.summarizeButton}
title={isSummarizing ? 'Summarizing...' : 'Summarize'}> onClick={summarizeAll}
<Sparkles size={14} /> disabled={isSummarizing || !currentStory || !connection || !model}
</button> title={isSummarizing ? 'Summarizing...' : 'Summarize'}>
</div> <Sparkles size={14} />
</button>
)}
</div> </div>
)} </div>
<ContentEditable <ContentEditable
autoLines autoLines
class={styles.input} class={styles.input}
@ -553,7 +565,7 @@ export const ChatPanel = () => {
<button <button
class={styles.sendButton} class={styles.sendButton}
onClick={handleSendMessage} onClick={handleSendMessage}
disabled={isDisabled || !input.trim()} disabled={isDisabled}
> >
Send Send
</button> </button>
@ -567,16 +579,14 @@ export const ChatPanel = () => {
<ChevronsRight size={14} /> <ChevronsRight size={14} />
</button> </button>
)} )}
{lastMessage?.role === 'assistant' && ( <button
<button class={styles.regenerateButton}
class={styles.regenerateButton} onClick={handleRegenerate}
onClick={handleRegenerate} disabled={isDisabled}
disabled={isDisabled} title="Regenerate last response"
title="Regenerate last response" >
> <RefreshCw size={14} />
<RefreshCw size={14} /> </button>
</button>
)}
</div> </div>
)} )}
</div> </div>