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

fix(chat): update response handling to stream and inline code block parsing VSCODE-620 #835

Merged

Conversation

Anemy
Copy link
Member

@Anemy Anemy commented Sep 25, 2024

VSCODE-620

These changes make all of the model responses feel a faster. We're now streaming them as they come in instead of building one string out of the response and then streaming that.
Also adds support for multiple code blocks. We now inline the code actions as the code comes in. Hopefully it's written in a way we can change that out as we update to a different code block identifier in an upcoming ticket.

Screenshot 2024-09-25 at 5 49 38 PM

@Anemy Anemy requested a review from nirinchev September 25, 2024 21:53
@Anemy Anemy requested a review from alenakhineika September 26, 2024 02:32

// This will stream all of the response content and create a string from it.
// It should only be used when the entire response is needed at one time.
async getChatResponseContent({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use this function anywhere? Can't find.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used for the namespace prompt currently, and will also be used with the intent prompt.

},
onIdentifierStreamed: (content: string) => {
this._streamCodeBlockActions({ runnableContent: content, stream });
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which cases processStreamFragment and onIdentifierStreamed can differ from the current call? Maybe we don't need to pass them as an argument? Same with codeBlockIdentifier. Looks like it constant anyway.

Copy link
Member Author

@Anemy Anemy Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives it a bit of flexibility so that if we want to add additional handlers for other languages it's easy. It is a bit of an early generalization, I wasn't thinking it adds too much complexity though. I'm happy simplifying it if that's preferred. We are only using it in this way at the moment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that it's isolated and potentially reusable. Processing the content of the stream while still displaying it to the user seems like a common-enough scenario that justifies making it a bit more general-purpose.

const contentToStream = contentSinceLastIdentifier.slice(
lastIndex,
endIndex
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if the code block can be mixed with the normal text withing one fragment? Or maybe the code block always takes the whole fragment.

Copy link
Member Author

@Anemy Anemy Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are tests for both cases, code block all in one fragment, code block and identifiers split between fragments. I was seeing the fragments are typically 1-3 characters.

@Anemy Anemy requested a review from alenakhineika September 26, 2024 13:14
Copy link
Contributor

@nirinchev nirinchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After spending some time with streamParsing.ts, I am 98% convinced the algorithm is correct, though it seems a bit more complex than strictly necessary. I don't think we need to refactor it and the tests are solid, so we can revisit at some point in the future. Similarly with the participant chat functions - we now have a handful of those, so I'd like to move them to a separate wrapper class in the future.

src/participant/streamParsing.ts Outdated Show resolved Hide resolved
src/participant/streamParsing.ts Outdated Show resolved Hide resolved
src/participant/streamParsing.ts Outdated Show resolved Hide resolved
src/participant/streamParsing.ts Outdated Show resolved Hide resolved
},
onIdentifierStreamed: (content: string) => {
this._streamCodeBlockActions({ runnableContent: content, stream });
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that it's isolated and potentially reusable. Processing the content of the stream while still displaying it to the user seems like a common-enough scenario that justifies making it a bit more general-purpose.

@Anemy Anemy merged commit 7eef0e7 into VSCODE-528-mongodb-copilot Sep 26, 2024
3 checks passed
@Anemy Anemy deleted the VSCODE-620-update-runnable-code-block-parsing branch September 26, 2024 16:09
nirinchev added a commit that referenced this pull request Sep 26, 2024
* VSCODE-528-mongodb-copilot:
  fix(chat): update response handling to stream and inline code block parsing VSCODE-620 (#835)
  feat(participant): route generic prompt by intent and update generic prompt VSCODE-572 (#830)

# Conflicts:
#	src/participant/participant.ts
#	src/participant/prompts/query.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants