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;
if (content) {
accumulatedContent += content;
if (currentWorld?.chatOnly && accumulatedContent.startsWith(prefix)) {
accumulatedContent = accumulatedContent.slice(prefix.length);
if (currentWorld?.chatOnly && accumulatedContent.trimStart().startsWith(prefix)) {
accumulatedContent = accumulatedContent.trimStart().slice(prefix.length).trimStart();
}
}
const reasoningContent = delta?.reasoning_content;
@ -258,8 +258,44 @@ export const ChatPanel = () => {
}
}, [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 () => {
if (!currentStory || !input.trim() || !connection || !model || isLoading) return;
if (!currentStory || !connection || !model || isLoading) return;
if (!input.trim()) {
if (lastMessage?.role === 'user') {
handleRegenerate();
}
return;
}
setInput('');
setIsLoading(true);
@ -275,7 +311,7 @@ export const ChatPanel = () => {
} finally {
setIsLoading(false);
}
}, [currentStory, input, connection, model, isLoading, sendMessage]);
}, [currentStory, input, connection, model, isLoading, sendMessage, handleRegenerate]);
const handleContinue = useCallback(async () => {
if (!currentStory || !connection || !model || isLoading) return;
@ -352,32 +388,6 @@ export const ChatPanel = () => {
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;
return (
@ -501,9 +511,9 @@ export const ChatPanel = () => {
)}
{currentStory && (
<div class={styles.inputContainer}>
{!currentWorld?.chatOnly && (
<div class={styles.optionsRow}>
<label class={styles.toggleContainer}>
<div class={styles.optionsRow}>
<label class={styles.toggleContainer}>
{!currentWorld?.chatOnly && (<>
<input
type="checkbox"
checked={enableThinking}
@ -514,19 +524,21 @@ export const ChatPanel = () => {
disabled={isDisabled}
/>
<span>Enable thinking</span>
</label>
<div class={styles.tokenCounter}>
{tokenCount && <span>{tokenCount.taken} / {tokenCount.total} tokens</span>}
<button
class={styles.summarizeButton}
onClick={summarizeAll}
disabled={isSummarizing || !currentStory || !connection || !model}
title={isSummarizing ? 'Summarizing...' : 'Summarize'}>
<Sparkles size={14} />
</button>
</div>
</>)}
</label>
<div class={styles.tokenCounter}>
{tokenCount && <span>{tokenCount.taken} / {tokenCount.total} tokens</span>}
{!currentWorld?.chatOnly && (<button
class={styles.summarizeButton}
onClick={summarizeAll}
disabled={isSummarizing || !currentStory || !connection || !model}
title={isSummarizing ? 'Summarizing...' : 'Summarize'}>
<Sparkles size={14} />
</button>
)}
</div>
)}
</div>
<ContentEditable
autoLines
class={styles.input}
@ -553,7 +565,7 @@ export const ChatPanel = () => {
<button
class={styles.sendButton}
onClick={handleSendMessage}
disabled={isDisabled || !input.trim()}
disabled={isDisabled}
>
Send
</button>
@ -567,16 +579,14 @@ export const ChatPanel = () => {
<ChevronsRight size={14} />
</button>
)}
{lastMessage?.role === 'assistant' && (
<button
class={styles.regenerateButton}
onClick={handleRegenerate}
disabled={isDisabled}
title="Regenerate last response"
>
<RefreshCw size={14} />
</button>
)}
<button
class={styles.regenerateButton}
onClick={handleRegenerate}
disabled={isDisabled}
title="Regenerate last response"
>
<RefreshCw size={14} />
</button>
</div>
)}
</div>