Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cody: new chat ui with stop generating button #53332

Merged
merged 24 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions client/cody-ui/src/Chat.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
}

.input-row {
position: relative;
display: flex;
flex-direction: column;
gap: 0.5rem;
Expand Down Expand Up @@ -49,3 +50,13 @@
gap: 0.5rem;
margin-bottom: 0.25rem;
}

.abort-button-container {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
position: absolute;
top: -2.5rem;
z-index: 100;
}
11 changes: 7 additions & 4 deletions client/cody-ui/src/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
needsEmailVerificationNotice: NeedsEmailVerificationNotice,
contextStatusComponent: ContextStatusComponent,
contextStatusComponentProps = {},
abortMessageInProgressComponent,
onAbortMessageInProgress,
abortMessageInProgressComponent: AbortMessageInProgressButton,
onAbortMessageInProgress = () => {},
isCodyEnabled,
}) => {
const [inputRows, setInputRows] = useState(5)
Expand Down Expand Up @@ -266,8 +266,6 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
copyButtonOnSubmit={copyButtonOnSubmit}
submitButtonComponent={SubmitButton}
chatInputClassName={chatInputClassName}
abortMessageInProgressComponent={abortMessageInProgressComponent}
onAbortMessageInProgress={onAbortMessageInProgress}
/>
)}

Expand All @@ -285,6 +283,11 @@ export const Chat: React.FunctionComponent<ChatProps> = ({
)}
</div>
) : null}
{messageInProgress && AbortMessageInProgressButton && (
<div className={classNames(styles.abortButtonContainer)}>
<AbortMessageInProgressButton onAbortMessageInProgress={onAbortMessageInProgress} />
</div>
)}
<div className={styles.textAreaContainer}>
<TextArea
className={classNames(styles.chatInput, chatInputClassName)}
Expand Down
6 changes: 0 additions & 6 deletions client/cody-ui/src/chat/Transcript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ export const Transcript: React.FunctionComponent<
feedbackButtonsOnSubmit?: (text: string) => void
copyButtonOnSubmit?: CopyButtonProps['copyButtonOnSubmit']
submitButtonComponent?: React.FunctionComponent<ChatUISubmitButtonProps>
abortMessageInProgressComponent?: React.FunctionComponent<{ onAbortMessageInProgress: () => void }>
onAbortMessageInProgress?: () => void
} & TranscriptItemClassNames
> = React.memo(function TranscriptContent({
transcript,
Expand All @@ -56,8 +54,6 @@ export const Transcript: React.FunctionComponent<
copyButtonOnSubmit,
submitButtonComponent,
chatInputClassName,
abortMessageInProgressComponent,
onAbortMessageInProgress,
}) {
const transcriptContainerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
Expand Down Expand Up @@ -145,8 +141,6 @@ export const Transcript: React.FunctionComponent<
copyButtonOnSubmit={copyButtonOnSubmit}
submitButtonComponent={submitButtonComponent}
chatInputClassName={chatInputClassName}
abortMessageInProgressComponent={abortMessageInProgressComponent}
onAbortMessageInProgress={onAbortMessageInProgress}
/>
)}
</div>
Expand Down
83 changes: 51 additions & 32 deletions client/cody-ui/src/chat/TranscriptItem.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,26 @@
}

.row {
position: relative;
border-bottom-width: 1px;
border-bottom-style: solid;

display: flex;
flex-direction: column;
gap: var(--spacing);

padding: var(--spacing);
}

.assistant-row:before {
position: absolute;
top: 0;
left: 0;

width: 0.1em;
height: 100%;

content: '';
background-image: linear-gradient(to bottom, #b200f8, #ff5543, #00cbec);
}

.row:last-child {
Expand All @@ -21,45 +35,20 @@
}

.row:only-child {
/* For the welcome message, make it visually consume the entire height instead of being a
discrete message. */
flex: 1;
/* For the welcome message */
border-bottom: none;
}

.participant {
font-weight: bold;
display: flex;
justify-content: space-between;
}

.participant-name {
display: flex;
gap: 0.25rem;
align-items: center;

margin: 0;
padding: var(--spacing) var(--spacing) 0 var(--spacing);

font-size: 0.8rem;
font-weight: bold;
height: 2rem;
}

.participant-avatar {
height: 1rem;
width: 1rem;
.row:hover > .header-container,
.row:hover > .footer-container {
visibility: visible;
}

.actions {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 var(--spacing);
}

.content-padding {
padding: 0 var(--spacing) var(--spacing) var(--spacing);
padding: 0 0 var(--spacing) 0;
}

.content {
Expand All @@ -84,10 +73,40 @@
margin-bottom: 0;
}

.header-container {
position: absolute;
right: var(--spacing);
top: calc(var(--spacing) / 4);

visibility: hidden;
}

.editing-container {
position: absolute;
right: var(--spacing);
top: var(--spacing);

visibility: visible;
}

.editing-label {
margin: 0;
padding-top: 0.1rem;
padding-bottom: 0.5rem;
opacity: 0.5;
}

.footer-container {
position: absolute;
bottom: calc(var(--spacing) / 4);
right: var(--spacing);

visibility: hidden;
}

.feedback-edit-buttons-container {
display: flex;
gap: 0.25rem;
align-items: center;

margin: 0;
padding: 0 var(--spacing) var(--spacing) var(--spacing);
Expand Down
68 changes: 28 additions & 40 deletions client/cody-ui/src/chat/TranscriptItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
CopyButtonProps,
ChatUISubmitButtonProps,
} from '../Chat'
import { CodySvg } from '../utils/icons'

import { BlinkingCursor } from './BlinkingCursor'
import { CodeBlocks } from './CodeBlocks'
Expand Down Expand Up @@ -76,8 +75,6 @@ export const TranscriptItem: React.FunctionComponent<
copyButtonOnSubmit,
submitButtonComponent: SubmitButton,
chatInputClassName,
abortMessageInProgressComponent: AbortMessageInProgressButton,
onAbortMessageInProgress = () => {},
}) {
const [formInput, setFormInput] = useState<string>(message.displayText ?? '')
const textarea =
Expand Down Expand Up @@ -123,43 +120,25 @@ export const TranscriptItem: React.FunctionComponent<
className={classNames(
styles.row,
transcriptItemClassName,
message.speaker === 'human' ? humanTranscriptItemClassName : null
message.speaker === 'human' ? humanTranscriptItemClassName : styles.assistantRow
)}
>
<header className={classNames(styles.participant, transcriptItemParticipantClassName)}>
<h2 className={styles.participantName}>
{message.speaker === 'assistant' ? (
<>
<CodySvg className={styles.participantAvatar} /> Cody
</>
) : (
'Me'
{/* display edit buttons on last user message, feedback buttons on last assistant message only */}
{EditButtonContainer && beingEdited && <p className={classNames(styles.editingLabel)}>Editing...</p>}
{showEditButton && EditButtonContainer && editButtonOnSubmit && TextArea && message.speaker === 'human' && (
<header
className={classNames(
beingEdited ? styles.editingContainer : styles.headerContainer,
transcriptItemParticipantClassName
)}
</h2>
{/* display edit buttons on last user message, feedback buttons on last assistant message only */}
<div className={styles.participantName}>
{showEditButton &&
EditButtonContainer &&
editButtonOnSubmit &&
TextArea &&
message.speaker === 'human' && (
<EditButtonContainer
className={styles.FeedbackEditButtonsContainer}
messageBeingEdited={beingEdited}
setMessageBeingEdited={setBeingEdited}
/>
)}
{showFeedbackButtons &&
FeedbackButtonsContainer &&
feedbackButtonsOnSubmit &&
message.speaker === 'assistant' && (
<FeedbackButtonsContainer
className={styles.FeedbackEditButtonsContainer}
feedbackButtonsOnSubmit={feedbackButtonsOnSubmit}
/>
)}
</div>
</header>
>
<EditButtonContainer
className={styles.FeedbackEditButtonsContainer}
messageBeingEdited={beingEdited}
setMessageBeingEdited={setBeingEdited}
/>
</header>
)}
{message.contextFiles && message.contextFiles.length > 0 && (
<div className={styles.actions}>
<ContextFiles
Expand All @@ -182,10 +161,19 @@ export const TranscriptItem: React.FunctionComponent<
) : inProgress ? (
<BlinkingCursor />
) : null}
{inProgress && AbortMessageInProgressButton && (
<AbortMessageInProgressButton onAbortMessageInProgress={onAbortMessageInProgress} />
)}
</div>
{showFeedbackButtons &&
FeedbackButtonsContainer &&
feedbackButtonsOnSubmit &&
message.speaker === 'assistant' && (
<footer className={classNames(styles.footerContainer, transcriptItemParticipantClassName)}>
{/* display edit buttons on last user message, feedback buttons on last assistant message only */}
<FeedbackButtonsContainer
className={styles.FeedbackEditButtonsContainer}
feedbackButtonsOnSubmit={feedbackButtonsOnSubmit}
/>
</footer>
)}
</div>
)
})
3 changes: 3 additions & 0 deletions client/cody/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ Starting from `0.2.0`, Cody is using `major.EVEN_NUMBER.patch` for release versi

### Added

- `Stop Generating` button to cancel a request and stop Cody's response. [pull/53332](https://github.com/sourcegraph/sourcegraph/pull/53332)

### Fixed

### Changed

- Completions: Updating configuration no longer requires reloading the extension. [pull/53401](https://github.com/sourcegraph/sourcegraph/pull/53401)
- New chat layout. [pull/53332](https://github.com/sourcegraph/sourcegraph/pull/53332)

## [0.2.4]

Expand Down
8 changes: 8 additions & 0 deletions client/cody/src/chat/ChatViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ export class ChatViewProvider implements vscode.WebviewViewProvider, vscode.Disp
this.transcript.removeLastInteraction()
await this.onHumanMessageSubmitted(message.text, 'user')
break
case 'abort':
this.cancelCompletion()
this.onCompletionEnd()
break
case 'executeRecipe':
await this.executeRecipe(message.recipe)
break
Expand Down Expand Up @@ -357,6 +361,10 @@ export class ChatViewProvider implements vscode.WebviewViewProvider, vscode.Disp
void this.multiplexer.notifyTurnComplete()
},
onError: (err, statusCode) => {
if (err === 'aborted') {
this.onCompletionEnd()
return
}
// Display error message as assistant response
this.transcript.addErrorAsAssistantResponse(err)
// Log users out on unauth error
Expand Down
1 change: 1 addition & 0 deletions client/cody/src/chat/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type WebviewMessage =
| { command: 'openFile'; filePath: string }
| { command: 'edit'; text: string }
| { command: 'insert'; text: string }
| { command: 'abort' }

/**
* A message sent from the extension host to the webview.
Expand Down
Loading
Loading