Skip to content

Commit fb5d1fe

Browse files
committed
feat: Continuation logic & prompt improvements
1 parent 9f772be commit fb5d1fe

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,12 @@
119119
120120
function handleSaveEdit() {
121121
if (message.role === 'user') {
122+
// For user messages, trim to avoid accidental whitespace
122123
onEditWithBranching?.(message, editedContent.trim());
123124
} else {
124-
onEditWithReplacement?.(message, editedContent.trim(), shouldBranchAfterEdit);
125+
// For assistant messages, preserve exact content including trailing whitespace
126+
// This is important for the Continue feature to work properly
127+
onEditWithReplacement?.(message, editedContent, shouldBranchAfterEdit);
125128
}
126129
127130
isEditing = false;
@@ -130,6 +133,7 @@
130133
131134
function handleSaveEditOnly() {
132135
if (message.role === 'user') {
136+
// For user messages, trim to avoid accidental whitespace
133137
onEditUserMessagePreserveResponses?.(message, editedContent.trim());
134138
}
135139

tools/server/webui/src/lib/stores/chat.svelte.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,20 +1692,30 @@ class ChatStore {
16921692
this.setConversationLoading(this.activeConversation.id, true);
16931693
this.clearConversationStreaming(this.activeConversation.id);
16941694

1695+
// Get current content (includes any edits made to the message)
1696+
// This comes from activeMessages which is kept in sync with the database
16951697
const originalContent = messageToContinue.content;
16961698
const originalThinking = messageToContinue.thinking || '';
16971699

1698-
// Get conversation context up to and including the message to continue
1699-
const conversationContext = this.activeMessages.slice(0, messageIndex + 1);
1700+
// Get conversation context up to (but not including) the message to continue
1701+
const conversationContext = this.activeMessages.slice(0, messageIndex);
17001702

17011703
// Add a synthetic "continue" prompt to signal continuation
1704+
// We check if original content ends with whitespace to preserve it in the instruction
1705+
const endsWithWhitespace = /\s$/.test(originalContent);
1706+
const continueInstruction = endsWithWhitespace
1707+
? 'Continue your response. Start directly without adding extra spacing.'
1708+
: 'Continue your response from where you left off.';
1709+
17021710
const continuePrompt: ApiChatMessageData = {
17031711
role: 'user',
1704-
content: 'Continue from where you left off.'
1712+
content: continueInstruction
17051713
};
17061714

1715+
// Build context: all previous messages + assistant message + synthetic user prompt
1716+
// The user prompt is only sent to the API, not saved to the database
17071717
const contextWithContinue = [
1708-
...conversationContext.slice(0, -1).map((msg) => {
1718+
...conversationContext.map((msg) => {
17091719
if ('id' in msg && 'convId' in msg && 'timestamp' in msg) {
17101720
return msg as DatabaseMessage & { extra?: DatabaseMessageExtra[] };
17111721
}
@@ -1728,6 +1738,8 @@ class ChatStore {
17281738

17291739
onChunk: (chunk: string) => {
17301740
appendedContent += chunk;
1741+
// Preserve originalContent exactly as-is, including any trailing whitespace
1742+
// The concatenation naturally preserves any whitespace at the end of originalContent
17311743
const fullContent = originalContent + appendedContent;
17321744
this.setConversationStreaming(
17331745
messageToContinue.convId,

0 commit comments

Comments
 (0)