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

feat(ai): Make response parsing extensible #14196

Merged
merged 4 commits into from
Oct 2, 2024

Conversation

planger
Copy link
Contributor

@planger planger commented Sep 18, 2024

What it does

Turns the response parsing method of the chat agents into a more flexible algorithm that can work with multiple response content matchers. Each response content matcher has a start and an end regexp to define a match, as well as a contentFactory function that is invoked to turn the matched content into a specific ChatResponseContent object.

This way, clients can add and combine multiple response content matchers to process LLM responses and turn them into custom response parts, while still keeping the generically useful ones, like the matcher for code blocks, etc.

Additionally, the parsing method has a fallback content factory that will be applied to all unmatched parts. By default, this is the existing markdown content part, but this can be customized if needed.

Both, the response content matchers and the fallback content factory are configurable via DI.

Contributed on behalf of STMicroelectronics.

How to test

Ensure normal behavior is still working as expected. That is, we should test the processing and rendering of plain chat responses that contain an arbitrary mixture of markdown parts, code parts, and tool call parts.

In addition, one could test to customize the DefaultResponseContentFactory or register additional ResponseContentMatcherProvider.

    // Change the default response part
    rebind(DefaultResponseContentMatcherProvider).to(YourDefaultPartCustomization);
    // Add additional matchers
    bind(ResponseContentMatcherProvider).to(YourAdditionalResponseContentMatcherProvider);
    // Change default matchers (code)
    rebind(DefaultResponseContentFactory).to(YourCustomization);

Since the parsing is a bit of a dense code, I added unit tests for it.

Follow-ups

I tried to simplify the parsing. However, there is one aspect, which I found a bit confusing but is not changed by this PR:
The fall back to markdown, handling of tool calls, or parsing into specific parts is a bit spread across the code

  • 2x in parse()
  • 3x in addContentsToResponse, where we currently need to ensure, we prevent parsing, if the previous content was a tool call, which is also somewhat hidden.

Maybe there is an opportunity to further simplify this and parse this all in one place and one go.

Also it was unclear to me why we don't parse for specific content parts in case we have a isLanguageModelTextResponse === true case. This is actually changed so that it now uses the parseContents function to obtain the content parts instead of creating a plain markdown part either way, which feels more consistent.

Review checklist

Reminder for reviewers

Turns the response parsing method into a more flexible algorithm
that can work with multiple response content matchers. Each response
content matcher has a start and end regexp to define a match, as well
as a `contentFactory` function that turns the matched content into a
`ChatResponseContent` object.

Additionally, the parsing method has a fallback content factory that
will be applied to all unmatched parts, e.g. markdown by default.

Both, the response content matchers and the fallback content factory
and the list of matchers are extensible via DI.

Contributed on behalf of STMicroelectronics.
Copy link
Contributor

@eneufeld eneufeld left a comment

Choose a reason for hiding this comment

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

I like the tests.
Maybe we could improve the readability a bit as the findEarliestMatch and parseContents methods are hard to read.
I will take a second look maybe I find something to suggest

packages/ai-chat/src/common/parse-contents.ts Outdated Show resolved Hide resolved
packages/ai-chat/src/common/chat-model.ts Outdated Show resolved Hide resolved
packages/ai-chat/src/common/chat-agents.ts Outdated Show resolved Hide resolved
* Make parse contents more readable
* Only send out one notification when adding multiple content objects
* Remove superfluous optional modifier
@planger
Copy link
Contributor Author

planger commented Sep 30, 2024

@eneufeld Thank you for the review. I've addressed your comments. Can you please re-check and re-test? Thank you!

@planger planger requested a review from eneufeld October 1, 2024 12:33
Copy link
Contributor

@eneufeld eneufeld left a comment

Choose a reason for hiding this comment

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

Works for me, thank you

@planger planger marked this pull request as ready for review October 1, 2024 14:39
Copy link
Contributor

@JonasHelming JonasHelming left a comment

Choose a reason for hiding this comment

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

LGTM!

@planger planger merged commit f6ace67 into eclipse-theia:master Oct 2, 2024
11 checks passed
@planger planger deleted the extract-parse-content branch October 2, 2024 07:19
@planger planger added this to the 1.55.0 milestone Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants