Skip to content

Commit 2de05ac

Browse files
committed
Fix AI Assistant restart to prevent token waste
When clicking 'Restart Chat', the LLM provider was still receiving the entire conversation history in API calls, wasting tokens and increasing costs. Root cause: @openassistant library uses singleton instances that persist across React component remounts, maintaining internal messageHistory. Solution: - Extract restartChat function from useAssistant hook - Call it to clear library's internal singleton message cache - Force React component remount using key prop - Clear Redux message state This eliminates token waste and reduces API costs for all users. Signed-off-by: Akash Rai <akashtooop@gmail.com>
1 parent f468e3a commit 2de05ac

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

src/ai-assistant/src/components/ai-assistant-component.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// Copyright contributors to the kepler.gl project
33

4-
import React, {useEffect, useState} from 'react';
4+
import React, {useEffect, useRef, useState} from 'react';
55
import {useDispatch, useSelector} from 'react-redux';
66
import styled from 'styled-components';
77
import {textColorLT, theme} from '@kepler.gl/styles';
@@ -59,6 +59,8 @@ export function AiAssistantComponent() {
5959

6060
const [ideas, setIdeas] = useState<{title: string; description: string}[]>([]);
6161

62+
const [restartKey, setRestartKey] = useState<number>(0);
63+
6264
// get dataset meta data and re-initialize assistant when datasets or layers change
6365
useEffect(() => {
6466
const metaData = getDatasetContext(visState?.datasets, visState?.layers || []);
@@ -70,7 +72,12 @@ export function AiAssistantComponent() {
7072
const instructions = `${INSTRUCTIONS}\n\n${datasetMetaData}`;
7173

7274
// generate ideas from LLM
73-
const {temporaryPrompt} = useAssistant({...assistantProps, instructions});
75+
const {temporaryPrompt, restartChat: libraryRestartChat} = useAssistant({...assistantProps, instructions});
76+
77+
const restartChatRef = useRef(libraryRestartChat);
78+
useEffect(() => {
79+
restartChatRef.current = libraryRestartChat;
80+
}, [libraryRestartChat]);
7481

7582
const generateIdeas = async () => {
7683
try {
@@ -97,9 +104,16 @@ export function AiAssistantComponent() {
97104
// eslint-disable-next-line react-hooks/exhaustive-deps
98105
}, [datasetMetaData]);
99106

100-
const onRestartAssistant = () => {
101-
// clean up aiAssistant state
107+
const onRestartAssistant = async () => {
102108
dispatch(updateAiAssistantMessages([]));
109+
110+
try {
111+
await restartChatRef.current();
112+
} catch (e) {
113+
console.error('Error restarting chat:', e);
114+
}
115+
116+
setRestartKey(prev => prev + 1);
103117
};
104118

105119
const onMessagesUpdated = (messages: MessageModel[]) => {
@@ -117,6 +131,7 @@ export function AiAssistantComponent() {
117131
return (
118132
<StyledAiAssistantComponent className="ai-assistant-component">
119133
<AiAssistant
134+
key={restartKey}
120135
{...assistantProps}
121136
instructions={instructions}
122137
theme={theme.textColor === textColorLT ? 'light' : 'dark'}

0 commit comments

Comments
 (0)