From 3ef03eaf4f7996643b1c6bcc63f1a043c49c9075 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 4 Jul 2026 16:08:02 -0700 Subject: [PATCH 01/11] fix character could see themselves as RAGd --- client/src/engine/chat/transcript.test.ts | 9 +++++++++ client/src/engine/chat/transcript.ts | 6 +++++- client/src/engine/memory_rag_helper.ts | 10 ++++++---- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/client/src/engine/chat/transcript.test.ts b/client/src/engine/chat/transcript.test.ts index 62f1f3f..8868da6 100644 --- a/client/src/engine/chat/transcript.test.ts +++ b/client/src/engine/chat/transcript.test.ts @@ -49,6 +49,15 @@ describe('ConversationTranscript offscreen-mention RAG', () => { ({ transcript, live } = freshTranscript([ALICE.id, BOB.id, CAROL.id])); }); + it("does not return self as RAG'd character", async () => { + transcript = await say(transcript, CAROL, 'Hello Eve'); + transcript = transcript.addParticipant(EVE).updatedTranscript; + const raggedFromEvePerspective = transcript.getMentionedOffscreenCharacterIds(EVE.id); + expect(raggedFromEvePerspective).toHaveLength(0); + const raggedFromCarolPerspective = transcript.getMentionedOffscreenCharacterIds(CAROL.id); + expect(raggedFromCarolPerspective).toHaveLength(1); + }); + it('handles first message being a join message', async () => { transcript = await say(transcript, CAROL, 'Hello everyone'); transcript = transcript.addParticipant(EVE).updatedTranscript; diff --git a/client/src/engine/chat/transcript.ts b/client/src/engine/chat/transcript.ts index 85ba6d3..6723a5f 100644 --- a/client/src/engine/chat/transcript.ts +++ b/client/src/engine/chat/transcript.ts @@ -773,7 +773,11 @@ export class ConversationTranscript { } for (const mentionedCharacterId of this.ragHelper.getMentionedCharacterIds(message.message.id)) { - if (seen.has(mentionedCharacterId) || this.isCurrentlyPresent(mentionedCharacterId)) { + if ( + seen.has(mentionedCharacterId) || + this.isCurrentlyPresent(mentionedCharacterId) || + mentionedCharacterId === focusedCharacterId + ) { continue; } diff --git a/client/src/engine/memory_rag_helper.ts b/client/src/engine/memory_rag_helper.ts index 3600ca1..e3f9b18 100644 --- a/client/src/engine/memory_rag_helper.ts +++ b/client/src/engine/memory_rag_helper.ts @@ -51,10 +51,12 @@ export class MemoryRAGHelper { return []; } - return entry.mentionedCharacterIds.map((mentionedCharacterId) => ({ - mentionedCharacterId, - content: () => this.getRagContent(fromPerspectiveId, mentionedCharacterId, entry.senderId), - })); + return entry.mentionedCharacterIds + .filter((id) => id !== fromPerspectiveId) + .map((mentionedCharacterId) => ({ + mentionedCharacterId, + content: () => this.getRagContent(fromPerspectiveId, mentionedCharacterId, entry.senderId), + })); } public serialize(): SerializedRagHelper { From 7ce80572bb27a236f146b91743c098eddadbde33 Mon Sep 17 00:00:00 2001 From: mistval Date: Sun, 26 Jul 2026 13:22:46 -0700 Subject: [PATCH 02/11] fix chat often not scrolling down after image added --- client/src/components/ChatPane.tsx | 233 ++++++++++++++--------------- 1 file changed, 115 insertions(+), 118 deletions(-) diff --git a/client/src/components/ChatPane.tsx b/client/src/components/ChatPane.tsx index 3ca8ef9..23365b1 100644 --- a/client/src/components/ChatPane.tsx +++ b/client/src/components/ChatPane.tsx @@ -50,7 +50,8 @@ export default function ChatPane() { const [editingMessageId, setEditingMessageId] = useState(undefined); const [editingMessageDraft, setEditingMessageDraft] = useState(''); - const transcriptContainerRef = useRef(null); + const transcriptContainerOuterRef = useRef(null); + const transcriptContainerInnerRef = useRef(null); const autoScrollUnlockedRef = useRef(true); const inputRef = useRef(null); @@ -232,21 +233,8 @@ export default function ChatPane() { return remaining <= 24; }; - const scrollTranscriptToBottom = () => { - setTimeout(() => { - const container = transcriptContainerRef.current; - if (!container || !autoScrollUnlockedRef.current) { - return; - } - - requestAnimationFrame(() => { - container.scrollTop = container.scrollHeight; - }); - }, 25); - }; - const handleTranscriptScroll = () => { - const container = transcriptContainerRef.current; + const container = transcriptContainerOuterRef.current; if (!container) { return; } @@ -302,8 +290,20 @@ export default function ChatPane() { }, [transcript?.countAllMessages() === 0]); useEffect(() => { - scrollTranscriptToBottom(); - }, [transcript]); + if (!transcriptContainerInnerRef.current) { + return; + } + + const observer = new ResizeObserver(() => { + if (autoScrollUnlockedRef.current && transcriptContainerOuterRef.current) { + transcriptContainerOuterRef.current.scrollTop = transcriptContainerOuterRef.current.scrollHeight; + } + }); + + observer.observe(transcriptContainerInnerRef.current); + + return () => observer.disconnect(); + }, [transcriptContainerInnerRef.current]); if (!scenario || !userLocation) { return undefined; @@ -396,135 +396,132 @@ export default function ChatPane() {
- {transcript.countAllMessages() === 0 && ( -
- {participants[0]!.id === userCharacter.id - ? 'Say something to start the conversation, or choose an NPC to speak.' - : isPaused - ? 'Click Speak on a character card to choose who talks next, or Start Chat to let them talk on their own.' - : 'Conversation in progress...'} -
- )} - {transcript.getVisibleMessages(userCharacter.id).map((entry) => ( -
- {entry.isImageMessage() ? ( - Generated - ) : editingMessageId === entry.getId() && entry.isCharacterChatMessage() ? ( -
-
- {entry.getSpeakerName()}: -
-