Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 6b6008e

Browse files
Add stop generating button to cody web (#53191)
Add stop generating button for in progress message for cody in web. <img width="760" alt="image" src="https://github.com/sourcegraph/sourcegraph/assets/22571395/8ea16443-a125-4a73-8859-eb815cdd89e3"> https://www.loom.com/share/811352d2fb6942ff9851c9dedda281e1 ## Test plan - visit /cody - ask a question - click on stop generating button - reload the page
1 parent 7b07d55 commit 6b6008e

File tree

7 files changed

+74
-3
lines changed

7 files changed

+74
-3
lines changed

client/cody-shared/src/chat/useClient.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export interface CodyClient {
6868
setEditorScope: (editor: Editor) => void
6969
toggleIncludeInferredRepository: () => void
7070
toggleIncludeInferredFile: () => void
71+
abortMessageInProgress: () => void
7172
}
7273

7374
interface CodyClientProps {
@@ -91,6 +92,7 @@ export const useClient = ({
9192
const [transcript, setTranscriptState] = useState<Transcript | null>(initialTranscript)
9293
const [chatMessages, setChatMessagesState] = useState<ChatMessage[]>([])
9394
const [isMessageInProgress, setIsMessageInProgressState] = useState<boolean>(false)
95+
const [abortMessageInProgressInternal, setAbortMessageInProgress] = useState<() => void>(() => () => undefined)
9496

9597
const messageInProgress: ChatMessage | null = useMemo(() => {
9698
if (isMessageInProgress) {
@@ -104,6 +106,18 @@ export const useClient = ({
104106
return null
105107
}, [chatMessages, isMessageInProgress])
106108

109+
const abortMessageInProgress = useCallback(() => {
110+
abortMessageInProgressInternal()
111+
112+
transcript
113+
?.toChatPromise()
114+
.then(messages => {
115+
setChatMessagesState(messages)
116+
setIsMessageInProgressState(false)
117+
})
118+
.catch(error => console.error(`aborting in progress message failed: ${error}`))
119+
}, [abortMessageInProgressInternal, transcript, setChatMessagesState, setIsMessageInProgressState])
120+
107121
const setTranscript = useCallback(async (transcript: Transcript): Promise<void> => {
108122
const messages = await transcript.toChatPromise()
109123

@@ -256,8 +270,9 @@ export const useClient = ({
256270

257271
const responsePrefix = interaction.getAssistantMessage().prefix ?? ''
258272
let rawText = ''
259-
return new Promise(resolve => {
260-
chatClient.chat(prompt, {
273+
274+
const updatedTranscript = await new Promise<Transcript | null>(resolve => {
275+
const abort = chatClient.chat(prompt, {
261276
onChange(_rawText) {
262277
rawText = _rawText
263278

@@ -297,7 +312,16 @@ export const useClient = ({
297312
resolve(transcript)
298313
},
299314
})
315+
316+
setAbortMessageInProgress(() => () => {
317+
abort()
318+
resolve(transcript)
319+
})
300320
})
321+
322+
setAbortMessageInProgress(() => () => undefined)
323+
324+
return updatedTranscript
301325
},
302326
[
303327
config,
@@ -310,6 +334,7 @@ export const useClient = ({
310334
chatClient,
311335
isMessageInProgress,
312336
onEvent,
337+
setAbortMessageInProgress,
313338
]
314339
)
315340

@@ -363,6 +388,7 @@ export const useClient = ({
363388
editMessage,
364389
toggleIncludeInferredRepository,
365390
toggleIncludeInferredFile,
391+
abortMessageInProgress,
366392
}),
367393
[
368394
transcript,
@@ -381,6 +407,7 @@ export const useClient = ({
381407
editMessage,
382408
toggleIncludeInferredRepository,
383409
toggleIncludeInferredFile,
410+
abortMessageInProgress,
384411
]
385412
)
386413
}

client/cody-shared/src/sourcegraph-api/completions/browserClient.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ export class SourcegraphBrowserCompletionsClient extends SourcegraphCompletionsC
5858
abort.abort()
5959
console.error(error)
6060
})
61-
return () => abort.abort()
61+
return () => {
62+
abort.abort()
63+
}
6264
}
6365
}

client/cody-ui/src/Chat.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ interface ChatProps extends ChatClassNames {
4141
setSuggestions?: (suggestions: undefined | []) => void
4242
needsEmailVerification?: boolean
4343
needsEmailVerificationNotice?: React.FunctionComponent
44+
abortMessageInProgressComponent?: React.FunctionComponent<{ onAbortMessageInProgress: () => void }>
45+
onAbortMessageInProgress?: () => void
4446
}
4547

4648
interface ChatClassNames extends TranscriptItemClassNames {
@@ -128,6 +130,8 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
128130
needsEmailVerificationNotice: NeedsEmailVerificationNotice,
129131
contextStatusComponent: ContextStatusComponent,
130132
contextStatusComponentProps = {},
133+
abortMessageInProgressComponent,
134+
onAbortMessageInProgress,
131135
}) => {
132136
const [inputRows, setInputRows] = useState(5)
133137
const [historyIndex, setHistoryIndex] = useState(inputHistory.length)
@@ -254,6 +258,8 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
254258
copyButtonOnSubmit={copyButtonOnSubmit}
255259
submitButtonComponent={SubmitButton}
256260
chatInputClassName={chatInputClassName}
261+
abortMessageInProgressComponent={abortMessageInProgressComponent}
262+
onAbortMessageInProgress={onAbortMessageInProgress}
257263
/>
258264
)}
259265

client/cody-ui/src/chat/Transcript.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export const Transcript: React.FunctionComponent<
3232
feedbackButtonsOnSubmit?: (text: string) => void
3333
copyButtonOnSubmit?: CopyButtonProps['copyButtonOnSubmit']
3434
submitButtonComponent?: React.FunctionComponent<ChatUISubmitButtonProps>
35+
abortMessageInProgressComponent?: React.FunctionComponent<{ onAbortMessageInProgress: () => void }>
36+
onAbortMessageInProgress?: () => void
3537
} & TranscriptItemClassNames
3638
> = React.memo(function TranscriptContent({
3739
transcript,
@@ -54,6 +56,8 @@ export const Transcript: React.FunctionComponent<
5456
copyButtonOnSubmit,
5557
submitButtonComponent,
5658
chatInputClassName,
59+
abortMessageInProgressComponent,
60+
onAbortMessageInProgress,
5761
}) {
5862
const transcriptContainerRef = useRef<HTMLDivElement>(null)
5963
useEffect(() => {
@@ -141,6 +145,8 @@ export const Transcript: React.FunctionComponent<
141145
copyButtonOnSubmit={copyButtonOnSubmit}
142146
submitButtonComponent={submitButtonComponent}
143147
chatInputClassName={chatInputClassName}
148+
abortMessageInProgressComponent={abortMessageInProgressComponent}
149+
onAbortMessageInProgress={onAbortMessageInProgress}
144150
/>
145151
)}
146152
</div>

client/cody-ui/src/chat/TranscriptItem.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ export const TranscriptItem: React.FunctionComponent<
5151
showFeedbackButtons: boolean
5252
copyButtonOnSubmit?: CopyButtonProps['copyButtonOnSubmit']
5353
submitButtonComponent?: React.FunctionComponent<ChatUISubmitButtonProps>
54+
abortMessageInProgressComponent?: React.FunctionComponent<{ onAbortMessageInProgress: () => void }>
55+
onAbortMessageInProgress?: () => void
5456
} & TranscriptItemClassNames
5557
> = React.memo(function TranscriptItemContent({
5658
message,
@@ -74,6 +76,8 @@ export const TranscriptItem: React.FunctionComponent<
7476
copyButtonOnSubmit,
7577
submitButtonComponent: SubmitButton,
7678
chatInputClassName,
79+
abortMessageInProgressComponent: AbortMessageInProgressButton,
80+
onAbortMessageInProgress = () => {},
7781
}) {
7882
const [formInput, setFormInput] = useState<string>(message.displayText ?? '')
7983
const textarea =
@@ -178,6 +182,9 @@ export const TranscriptItem: React.FunctionComponent<
178182
) : inProgress ? (
179183
<BlinkingCursor />
180184
) : null}
185+
{inProgress && AbortMessageInProgressButton && (
186+
<AbortMessageInProgressButton onAbortMessageInProgress={onAbortMessageInProgress} />
187+
)}
181188
</div>
182189
</div>
183190
)

client/web/src/cody/components/ChatUI/ChatUi.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const ChatUI: React.FC<IChatUIProps> = ({ codyChatStore }): JSX.Element =
4545
setScope,
4646
toggleIncludeInferredRepository,
4747
toggleIncludeInferredFile,
48+
abortMessageInProgress,
4849
} = codyChatStore
4950

5051
const [formInput, setFormInput] = useState('')
@@ -102,11 +103,29 @@ export const ChatUI: React.FC<IChatUIProps> = ({ codyChatStore }): JSX.Element =
102103
needsEmailVerificationNotice={NeedsEmailVerificationNotice}
103104
contextStatusComponent={ScopeSelector}
104105
contextStatusComponentProps={scopeSelectorProps}
106+
abortMessageInProgressComponent={AbortMessageInProgress}
107+
onAbortMessageInProgress={abortMessageInProgress}
105108
/>
106109
</>
107110
)
108111
}
109112

113+
interface IAbortMessageInProgressProps {
114+
onAbortMessageInProgress: () => void
115+
}
116+
117+
const AbortMessageInProgress: React.FunctionComponent<IAbortMessageInProgressProps> = React.memo(
118+
function AbortMessageInProgressButton({ onAbortMessageInProgress }) {
119+
return (
120+
<div className="d-flex justify-content-center w-100 mt-4 mb-2">
121+
<Button onClick={onAbortMessageInProgress} variant="secondary" outline={true} size="sm">
122+
Stop generating
123+
</Button>
124+
</div>
125+
)
126+
}
127+
)
128+
110129
export const ScrollDownButton = React.memo(function ScrollDownButtonContent({
111130
onClick,
112131
}: {

client/web/src/cody/useCodyChat.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export interface CodyChatStore
3131
| 'setEditorScope'
3232
| 'toggleIncludeInferredRepository'
3333
| 'toggleIncludeInferredFile'
34+
| 'abortMessageInProgress'
3435
> {
3536
readonly transcriptHistory: TranscriptJSON[]
3637
readonly loaded: boolean
@@ -65,6 +66,7 @@ export const codyChatStoreMock: CodyChatStore = {
6566
loadTranscriptFromHistory: () => Promise.resolve(),
6667
toggleIncludeInferredRepository: () => {},
6768
toggleIncludeInferredFile: () => {},
69+
abortMessageInProgress: () => {},
6870
}
6971

7072
interface CodyChatProps {
@@ -106,6 +108,7 @@ export const useCodyChat = ({
106108
setScope: setScopeInternal,
107109
setEditorScope,
108110
setTranscript,
111+
abortMessageInProgress,
109112
toggleIncludeInferredRepository: toggleIncludeInferredRepositoryInternal,
110113
toggleIncludeInferredFile: toggleIncludeInferredFileInternal,
111114
initializeNewChat: initializeNewChatInternal,
@@ -364,6 +367,7 @@ export const useCodyChat = ({
364367
setEditorScope,
365368
toggleIncludeInferredRepository,
366369
toggleIncludeInferredFile,
370+
abortMessageInProgress,
367371
}
368372
}
369373

0 commit comments

Comments
 (0)