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

Adding Generative AI Features to DartPad #3135

Merged
merged 82 commits into from
Feb 28, 2025
Merged

Conversation

csells
Copy link
Collaborator

@csells csells commented Feb 3, 2025

  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.

This PR adds the following generative AI features to DartPad:

  • Suggest Fix button added to the console to suggest a fix for a run-time error using the Gemini LLM

  • Suggest Fix button added to each error to suggest a fix for a compile-time using the Gemini LLM

    • Quick Fixes button to show the analysis-provided quick fixes for each error (not AI, but matches the AI-related feature)
  • Gemini | Generate Code menu item that provides a Prompt dialog containing the following features:

    • set of suggested prompts
    • a retrieval mechanism for the user's last prompt that's remembered between sessions
    • a per-prompt preference for whether to generate Dart or Flutter code, remembered between sessions
    • multi-line text box to gather the user's text prompt
    • support for up to 3 image attachments to send along with the user's text prompt
    • Cancel, Accept and Accept & Run buttons
    • Cmd+Enter (on the mac)/Control+Enter (not on a mac) keyboard shortcuts to invoke the Accept & Run button
    • invoking an Accept button will show the Generating Code dialog with the following features:
      • show syntax colorized code as its generated by the LLM
      • Cancel, Accept and Accept & Run buttons
      • Cmd+Enter (mac)/Control+Enter (not mac) keyboard shortcuts to invoke the Accept & Run button
  • Gemini | Update Code menu item that provides a Prompt dialog with the following differences:

    • the user's last prompt is specific to whether they're creating new code or updating existing code
    • the user's last chosen app type (Dart or Flutter) is specific to whether they're creating or updating code
    • the subsequent Generating Code dialog for updates has the following differences:
      • shows diff output as the LLM generates the code so the user can see the changes before accepting them

@devoncarew
Copy link
Member

Yup; for the problem view, there's no space between the problem text and the first action button:

Screenshot 2025-02-14 at 4 10 38 AM

For the spinner, it looks too large in context:

Screenshot 2025-02-14 at 4 11 18 AM

And, the contrast for the diff - between the text and the add/remove text style - seemed off. I'm not sure the colors I have are a strict improvement. Perhaps more pastel-like colors? 🤷 It would be hard to get good sets of colors for both light and dark themes.

@csells
Copy link
Collaborator Author

csells commented Feb 14, 2025

I totally seeing the padding issue with the quick fix icon. I'll fix it.

Can I talk you out of the size changes on the spinner? It matches the size of the title and it's easy to see w/o it being in the way or too large. I like it.

I know what you mean about the lighter colors. I'll take another look at that.

@johnpryan
Copy link
Contributor

This is looking good to me after the latest changes to the prompt, thanks @csells!

A few other pieces of feedback:

  • I would prefer to remove the "accept and run" button and make this behavior the default
  • The accept button should attempt to hot-reload the app rather than restart (you can test by switching your SDK to the the main channel)
  • The "generate fix suggestion" button is enabled for Dart scripts with normal print (non-error) output - we should only enable this button if there's an error in the console.
  • The Update existing code menu should auto-select Dart if the code snippet is a Dart script, (and vice-versa for Flutter)

@csells
Copy link
Collaborator Author

csells commented Feb 14, 2025

Excellent feedback, @johnpryan! A couple of follow up questions:

  • how do I tell if it there is an error in the console?
  • how do I tell if the code snippet is Dart or Flutter?

@johnpryan
Copy link
Contributor

how do I tell if it there is an error in the console?

If you find usages of the appendLineToConsole, you should be able to sort out when we are appending due to an error vs due to normal program output. You'll probably have to pipe that information through this function and go from there.

how do I tell if the code snippet is Dart or Flutter?

This is stored in AppModel._appIsFlutter

Hope this helps!

@devoncarew
Copy link
Member

Can I talk you out of the size changes on the spinner? It matches the size of the title and it's easy to see w/o it being in the way or too large. I like it.

It's subjective, but to me, the constrained size - in my patch - looks better. ymmv

@csells
Copy link
Collaborator Author

csells commented Feb 16, 2025

OK. I believe that I have addressed all of feedback from @johnpryan and @devoncarew:

  • add padding around the actions in the problem view
  • bound the size of the indeterminate progress spinner (I believe @devoncarew checked in a fix here?)
  • adjust the colors in the diff view
  • The accept button should attempt to hot-reload the app rather than restart
  • The "generate fix suggestion" button is enabled for Dart scripts with normal print (non-error) output - we should only enable this button if there's an error in the console.
  • The Update existing code menu should auto-select Dart if the code snippet is a Dart script, (and vice-versa for Flutter)
  • I would prefer to remove the "accept and run" button and make this behavior the default

The only real snag was detecting when an error was in the console, as described by this issue. In the meantime, I added a heuristic to appendLineToConsole that seems to work pretty well.

In addition, I fixed the following issues I found as I was testing:

  • separate Dart and Flutter prompt buttons; the Flutter prompts didn't make sense for Dart
  • add appType to suggestFix and specialized the models on the back end; otherwise it translates Dart to Flutter programs

@johnpryan
Copy link
Contributor

It seems like the prompt input and Flutter app text inputs are battling for focus, we should make sure we are unfocusing the Flutter app when the dialog opens:

dartpad-focus-issue 2025-02-18 09_38_22

@csells
Copy link
Collaborator Author

csells commented Feb 18, 2025

@johnpryan this looks like another JS focus issue. Any ideas how to deal with it? That's beyond my knowledge of the Flutter and HTML interaction model.

@johnpryan
Copy link
Contributor

The Flutter app should unfocus when blur() is called in the iframe's JS context. I would take a look into adding this functionality to frame.js and see if it fixes it. Flutter web apps should be respecting the browser's focus / blur() calls cc: @ditman

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The addition of generative AI features to DartPad is a great step forward. The new features, including the suggest fix button and the generate code menu item, will significantly enhance the user experience. The code is generally well-structured, but there are several areas where improvements can be made to enhance the code's maintainability, readability, and robustness.

Summary of Findings

  • Error Handling: The error handling in the _streamResponse function could be improved by providing more context-specific error messages and potentially logging the full stack trace for easier debugging.
  • Code Duplication: There is some code duplication in the _flutterSystemInstructions and _dartSystemInstructions methods. Consider refactoring these into a single method with a parameter to differentiate between Flutter and Dart instructions.
  • String Interpolation: Consider using string interpolation instead of string concatenation for better readability in several places, such as in the prompt variable in the suggestFix method.
  • Null Safety: Ensure that all nullable variables are properly handled to prevent null pointer exceptions. For example, in the _textOnly method, the response.text property is nullable and should be handled accordingly.
  • Code Readability: Improve code readability by adding more comments to explain complex logic, especially in the cleanCode method.

Assessment

This pull request introduces generative AI features to DartPad, which is a significant enhancement. The code is generally well-structured, and the new features seem promising. However, there are several areas where improvements can be made to enhance the code's maintainability, readability, and robustness. Addressing these comments before merging is highly recommended. Given the number of comments, it's important to have others review and approve this code before merging.

@csells
Copy link
Collaborator Author

csells commented Feb 26, 2025

the remaining conflicting code is strictly additive, so I have no idea why it's showing as conflicting.

Copy link
Member

@devoncarew devoncarew left a comment

Choose a reason for hiding this comment

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

🎉

@johnpryan johnpryan merged commit cca2502 into dart-lang:main Feb 28, 2025
18 checks passed
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.

5 participants