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

Open
wants to merge 62 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
79332f5
WIP: generate new snippet
csells Dec 29, 2024
7227679
WIP: gemini
csells Jan 3, 2025
d560d81
added Suggest Fix from AI feature
csells Jan 4, 2025
f250ff4
feature: generate code
csells Jan 4, 2025
25a582b
TODOs
csells Jan 4, 2025
44b48df
refactoring the generative model instructions and filtering out stray…
csells Jan 4, 2025
15d4412
tweaks to the API key management
csells Jan 5, 2025
c3a6936
test and dep tweaks
csells Jan 14, 2025
3e1b6ba
Merge branch 'main' of github.com:dart-lang/dart-pad into gen-ai
johnpryan Jan 16, 2025
986136b
Fix issues after merge with main branch
johnpryan Jan 16, 2025
77b1242
Add suggestFix
johnpryan Jan 16, 2025
850e5d6
initial support for streaming response
csells Jan 18, 2025
2c6131e
used fetch_client on the web to enable client-side streaming results …
csells Jan 19, 2025
9d815d9
adding note about why we're using fetch_client
csells Jan 19, 2025
0af52b6
replace NOTEs with TODOs when bug fixes lang
csells Jan 19, 2025
44c28b4
cleanup before refactoring PromptDialog
csells Jan 19, 2025
e6acdba
streaming code - end-to-end
csells Jan 19, 2025
184143f
show generated code as it's generated
csells Jan 20, 2025
aba048f
refactor to make suggestFix streaming
csells Jan 20, 2025
fce2288
tweak
csells Jan 20, 2025
514f56f
streaming fix suggestions
csells Jan 20, 2025
f35a757
show the OK buttons as disabled when it's not time to press them
csells Jan 20, 2025
39f6132
a little bit of UI cleanup and code refactoring
csells Jan 21, 2025
be09155
migrated to http v1.3.0 and removing FetchClient
csells Jan 21, 2025
9ca07f6
UI tweak
csells Jan 21, 2025
ee57a29
tweaks
csells Jan 21, 2025
30ca7f8
added support for updating existing code
csells Jan 21, 2025
16a2e02
end-to-end support for image attachments
csells Jan 21, 2025
4aed8f9
added a max attachment number we can adjust later (started at 3)
csells Jan 21, 2025
7f14d65
updated to show items in true reverse order in the attachment list
csells Jan 21, 2025
d99e4f8
image attachment zoom
csells Jan 21, 2025
cf0ed1d
tweak
csells Jan 21, 2025
255cfc5
add cmd+enter and ctrl+enter to the prompt dialog
csells Jan 21, 2025
4d991fe
Merge branch 'gen-ai' of github.com:csells/dart-pad into gen-ai
johnpryan Jan 21, 2025
184c44f
run grind build-storage-artifacts
johnpryan Jan 21, 2025
f3de266
Merge pull request #1 from johnpryan/gen-ai
csells Jan 28, 2025
33699a2
fixed updateCode and other tweaks
csells Jan 28, 2025
59cc7d3
gemini menu updates
csells Jan 28, 2025
e735a48
dialog polish
csells Jan 28, 2025
73fe491
fixed where the Gemini tagline goes
csells Jan 28, 2025
724a068
give the dialogs edges in dark and light mode
csells Jan 28, 2025
f95a451
Merge branch 'dart-lang:main' into gen-ai
csells Jan 29, 2025
5fa2d0c
disable gzip to enable client to get content as it's available
csells Jan 29, 2025
abe8912
limiting packages in system instructions; added fix suggestions to th…
csells Jan 31, 2025
5138fc4
system instructions tweak
csells Jan 31, 2025
d97407e
adding a gzip not
csells Jan 31, 2025
6056d9e
enable auto-run from the generate code dialog
csells Feb 2, 2025
f75e653
show quick fixes button next to the suggest fix button if analyzer sa…
csells Feb 2, 2025
7d3e998
remove unneeded editor services method
csells Feb 2, 2025
3ce03fe
added diff on update or suggest fix
csells Feb 2, 2025
953c440
fixed an async scrolling issue
csells Feb 2, 2025
c6b1e53
console crash and dark mode diff view support
csells Feb 2, 2025
2508a24
another attempt to fix the console scroll crash; fixup ReadOnlyDiffWi…
csells Feb 2, 2025
244f4a6
tweak
csells Feb 2, 2025
614fe69
added preset prompt buttons and a means for saving and restoring the …
csells Feb 2, 2025
e963e02
Merge branch 'dart-lang:main' into gen-ai
csells Feb 2, 2025
42dbdbe
show quick fix action button (lightbulb) next to suggest fix action b…
csells Feb 2, 2025
065a1f2
WIP: generate/update code based on Flutter | Dart
csells Feb 2, 2025
6fd05ed
allow the user to decide between Dart and Flutter when generating and…
csells Feb 3, 2025
35a5e1b
tweak
csells Feb 3, 2025
2e6bcfd
license header fixes
csells Feb 3, 2025
12bf342
review feedback updates
csells Feb 5, 2025
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ build/

# IDE configuration
.idea/
.vscode/
.vscode/
86 changes: 86 additions & 0 deletions pkgs/dart_services/lib/src/common_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:shelf_router/shelf_router.dart';
import 'analysis.dart';
import 'caching.dart';
import 'compiling.dart';
import 'generative_ai.dart';
import 'project_templates.dart';
import 'pub.dart';
import 'sdk.dart';
Expand All @@ -36,6 +37,7 @@ class CommonServerImpl {

late Analyzer analyzer;
late Compiler compiler;
late GenerativeAI ai;

CommonServerImpl(
this.sdk,
Expand All @@ -50,6 +52,8 @@ class CommonServerImpl {
await analyzer.init();

compiler = Compiler(sdk, storageBucket: storageBucket);

ai = GenerativeAI();
}

Future<void> shutdown() async {
Expand Down Expand Up @@ -82,6 +86,9 @@ class CommonServerApi {
router.post(r'/api/<apiVersion>/format', handleFormat);
router.post(r'/api/<apiVersion>/document', handleDocument);
router.post(r'/api/<apiVersion>/openInIDX', handleOpenInIdx);
router.post(r'/api/<apiVersion>/generateCode', generateCode);
router.post(r'/api/<apiVersion>/updateCode', updateCode);
router.post(r'/api/<apiVersion>/suggestFix', suggestFix);
return router;
}();

Expand Down Expand Up @@ -236,6 +243,85 @@ class CommonServerApi {
}
}

@Route.post('$apiPrefix/suggestFix')
Future<Response> suggestFix(Request request, String apiVersion) async {
if (apiVersion != api3) return unhandledVersion(apiVersion);

final suggestFixRequest =
api.SuggestFixRequest.fromJson(await request.readAsJson());

return _streamResponse(
'suggestFix',
impl.ai.suggestFix(
message: suggestFixRequest.errorMessage,
line: suggestFixRequest.line,
column: suggestFixRequest.column,
source: suggestFixRequest.source,
),
);
}

@Route.post('$apiPrefix/generateCode')
Future<Response> generateCode(Request request, String apiVersion) async {
if (apiVersion != api3) return unhandledVersion(apiVersion);

final generateCodeRequest =
api.GenerateCodeRequest.fromJson(await request.readAsJson());

return _streamResponse(
'generateCode',
impl.ai.generateCode(
appType: generateCodeRequest.appType,
prompt: generateCodeRequest.prompt,
attachments: generateCodeRequest.attachments,
),
);
}

@Route.post('$apiPrefix/updateCode')
Future<Response> updateCode(Request request, String apiVersion) async {
if (apiVersion != api3) return unhandledVersion(apiVersion);

final updateCodeRequest =
api.UpdateCodeRequest.fromJson(await request.readAsJson());

return _streamResponse(
'updateCode',
impl.ai.updateCode(
appType: updateCodeRequest.appType,
prompt: updateCodeRequest.prompt,
source: updateCodeRequest.source,
attachments: updateCodeRequest.attachments,
),
);
}

Future<Response> _streamResponse(
String action,
Stream<String> inputStream,
) async {
try {
// NOTE: disabling gzip so that the client gets the data in the same
// chunks that the LLM is providing it to us. With gzip, the client
// receives the data all at once at the end of the stream.
final outputStream = inputStream.transform(utf8.encoder);
return Response.ok(
outputStream,
headers: {
'Content-Type': 'text/plain; charset=utf-8', // describe our bytes
'Content-Encoding': 'identity', // disable gzip
},
context: {'shelf.io.buffer_output': false}, // disable buffering
);
} catch (e) {
final logger = Logger(action);
logger.severe('$action error: $e');
return Response.internalServerError(
body: 'Failed to $action. Error: $e',
);
}
}

Response ok(Map<String, dynamic> json) {
return Response.ok(
_jsonEncoder.convert(json),
Expand Down
Loading
Loading