Skip to content

Commit

Permalink
chore: Update gemini example
Browse files Browse the repository at this point in the history
- Migrates the Gemini example to v1
- Updates the prompt generation method to be streaming
  • Loading branch information
dnys1 committed Oct 9, 2024
1 parent 0bf414b commit e9f04dd
Show file tree
Hide file tree
Showing 30 changed files with 1,436 additions and 357 deletions.
4 changes: 2 additions & 2 deletions examples/gemini/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ $ flutter pub get

Download Celest from the [Celest download page](https://celest.dev/download), and run the installer to get the Celest CLI.

Open this folder (`examples/gemini`) in your favorite IDE, navigate to the `celest/config` folder, and create a `.env` file. This will contain your Gemini API key. To learn more about obtaining an Gemini API key, follow this [guide](https://ai.google.dev/tutorials/setup).
Open this folder (`examples/gemini`) in your favorite IDE, navigate to the `celest` folder, and create a `.env` file. This will contain your Gemini API key. To learn more about obtaining an Gemini API key, follow this [guide](https://ai.google.dev/tutorials/setup).

The `.env` file you created in the `config` folder should contain the following key-value pair:
The `.env` file you created should contain the following key-value pair:

```shell
GEMINI_API_KEY=<your-gemini-api-key>
Expand Down
4 changes: 4 additions & 0 deletions examples/gemini/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ linter:

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

analyzer:
plugins:
- celest
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
// Generated by Celest. This file should not be modified manually, but
// it can be checked into version control.
// ignore_for_file: type=lint, unused_local_variable, unnecessary_cast, unnecessary_import
// ignore_for_file: type=lint, unused_local_variable, unnecessary_cast, unnecessary_import, deprecated_member_use

library; // ignore_for_file: no_leading_underscores_for_library_prefixes

import 'dart:io' as _$io;

import 'package:celest_core/_internal.dart';
import 'package:celest_core/src/util/globals.dart';
import 'package:celest_core/_internal.dart' as _$celest;
import 'package:celest_core/celest_core.dart' as _$celest;
import 'package:celest_core/src/util/globals.dart' as _$celest;
import 'package:gemini_example_client/src/functions.dart';
import 'package:gemini_example_client/src/serializers.dart';
import 'package:http/http.dart' as _$http;

import 'src/client/functions.dart';
import 'src/client/serializers.dart';
import 'package:native_storage/native_storage.dart' as _$native_storage;

final Celest celest = Celest();

enum CelestEnvironment {
local;

Uri get baseUri => switch (this) {
local => kIsWeb || !_$io.Platform.isAndroid
? Uri.parse('http://localhost:7777')
: Uri.parse('http://10.0.2.2:7777'),
local => _$celest.kIsWeb || !_$io.Platform.isAndroid
? Uri.parse('http://localhost:7786')
: Uri.parse('http://10.0.2.2:7786'),
};
}

class Celest with CelestBase {
class Celest with _$celest.CelestBase {
var _initialized = false;

late CelestEnvironment _currentEnvironment;

@override
late final NativeStorage nativeStorage = NativeStorage(scope: 'celest');
late final _$native_storage.NativeStorage nativeStorage =
_$native_storage.NativeStorage(scope: 'celest');

@override
late _$http.Client httpClient =
CelestHttpClient(secureStorage: nativeStorage.secure);
_$celest.CelestHttpClient(secureStorage: nativeStorage.secure);

late Uri _baseUri;

Expand All @@ -57,11 +58,14 @@ class Celest with CelestBase {

CelestFunctions get functions => _checkInitialized(() => _functions);

void init({CelestEnvironment environment = CelestEnvironment.local}) {
void init({
CelestEnvironment environment = CelestEnvironment.local,
_$celest.Serializers? serializers,
}) {
_currentEnvironment = environment;
_baseUri = environment.baseUri;
if (!_initialized) {
initSerializers();
initSerializers(serializers: serializers);
}
_initialized = true;
}
Expand Down
204 changes: 204 additions & 0 deletions examples/gemini/celest/client/lib/src/functions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// Generated by Celest. This file should not be modified manually, but
// it can be checked into version control.
// ignore_for_file: type=lint, unused_local_variable, unnecessary_cast, unnecessary_import, deprecated_member_use

library; // ignore_for_file: no_leading_underscores_for_library_prefixes

import 'dart:async' as _$async;
import 'dart:convert' as _$convert;

import 'package:celest/celest.dart' as _$celest;
import 'package:celest_core/celest_core.dart' as _$celest;
import 'package:celest_core/src/exception/cloud_exception.dart' as _$celest;
import 'package:celest_core/src/exception/serialization_exception.dart'
as _$celest;
import 'package:gemini_example_client/gemini_example_client.dart';
import 'package:google_generative_ai/src/error.dart' as _$error;
import 'package:http/src/exception.dart' as _$exception;

class CelestFunctions {
final gemini = CelestFunctionsGemini();
}

class CelestFunctionsGemini {
Never _throwError({
required int? $statusCode,
required Map<String, Object?> $body,
}) {
final $error = ($body['@error'] as Map<String, Object?>?);
$statusCode ??= ($error?['status'] as num?)?.toInt();
final $code = ($error?['code'] as String);
final $message = ($body['message'] as String?);
final $details = ($body['@'] as _$celest.JsonValue?) ??
($body['details'] as _$celest.JsonMap?);
switch ($code) {
case r'dart.convert.JsonUnsupportedObjectError':
throw _$celest.Serializers.instance
.deserialize<_$convert.JsonUnsupportedObjectError>($details);
case r'dart.async.AsyncError':
throw _$celest.Serializers.instance
.deserialize<_$async.AsyncError>($details);
case r'dart.async.TimeoutException':
throw _$celest.Serializers.instance
.deserialize<_$async.TimeoutException>($details);
case r'dart.core.Error':
throw _$celest.Serializers.instance.deserialize<Error>($details);
case r'dart.core.AssertionError':
throw _$celest.Serializers.instance
.deserialize<AssertionError>($details);
case r'dart.core.TypeError':
throw _$celest.Serializers.instance.deserialize<TypeError>($details);
case r'dart.core.ArgumentError':
throw _$celest.Serializers.instance
.deserialize<ArgumentError>($details);
case r'dart.core.RangeError':
throw _$celest.Serializers.instance.deserialize<RangeError>($details);
case r'dart.core.IndexError':
throw _$celest.Serializers.instance.deserialize<IndexError>($details);
case r'dart.core.UnsupportedError':
throw _$celest.Serializers.instance
.deserialize<UnsupportedError>($details);
case r'dart.core.UnimplementedError':
throw _$celest.Serializers.instance
.deserialize<UnimplementedError>($details);
case r'dart.core.StateError':
throw _$celest.Serializers.instance.deserialize<StateError>($details);
case r'dart.core.ConcurrentModificationError':
throw _$celest.Serializers.instance
.deserialize<ConcurrentModificationError>($details);
case r'dart.core.OutOfMemoryError':
throw _$celest.Serializers.instance
.deserialize<OutOfMemoryError>($details);
case r'dart.core.StackOverflowError':
throw _$celest.Serializers.instance
.deserialize<StackOverflowError>($details);
case r'dart.core.FormatException':
throw _$celest.Serializers.instance
.deserialize<FormatException>($details);
case r'dart.core.IntegerDivisionByZeroException':
throw _$celest.Serializers.instance
.deserialize<IntegerDivisionByZeroException>($details);
case r'celest.core.v1.CloudException':
throw _$celest.Serializers.instance
.deserialize<_$celest.CloudException>($details);
case r'celest.core.v1.CancelledException':
throw _$celest.Serializers.instance
.deserialize<_$celest.CancelledException>($details);
case r'celest.core.v1.UnknownError':
throw _$celest.Serializers.instance
.deserialize<_$celest.UnknownError>($details);
case r'celest.core.v1.BadRequestException':
throw _$celest.Serializers.instance
.deserialize<_$celest.BadRequestException>($details);
case r'celest.core.v1.UnauthorizedException':
throw _$celest.Serializers.instance
.deserialize<_$celest.UnauthorizedException>($details);
case r'celest.core.v1.NotFoundException':
throw _$celest.Serializers.instance
.deserialize<_$celest.NotFoundException>($details);
case r'celest.core.v1.AlreadyExistsException':
throw _$celest.Serializers.instance
.deserialize<_$celest.AlreadyExistsException>($details);
case r'celest.core.v1.PermissionDeniedException':
throw _$celest.Serializers.instance
.deserialize<_$celest.PermissionDeniedException>($details);
case r'celest.core.v1.ResourceExhaustedException':
throw _$celest.Serializers.instance
.deserialize<_$celest.ResourceExhaustedException>($details);
case r'celest.core.v1.FailedPreconditionException':
throw _$celest.Serializers.instance
.deserialize<_$celest.FailedPreconditionException>($details);
case r'celest.core.v1.AbortedException':
throw _$celest.Serializers.instance
.deserialize<_$celest.AbortedException>($details);
case r'celest.core.v1.OutOfRangeException':
throw _$celest.Serializers.instance
.deserialize<_$celest.OutOfRangeException>($details);
case r'celest.core.v1.UnimplementedError':
throw _$celest.Serializers.instance
.deserialize<_$celest.UnimplementedError>($details);
case r'celest.core.v1.InternalServerError':
throw _$celest.Serializers.instance
.deserialize<_$celest.InternalServerError>($details);
case r'celest.core.v1.UnavailableError':
throw _$celest.Serializers.instance
.deserialize<_$celest.UnavailableError>($details);
case r'celest.core.v1.DataLossError':
throw _$celest.Serializers.instance
.deserialize<_$celest.DataLossError>($details);
case r'celest.core.v1.DeadlineExceededError':
throw _$celest.Serializers.instance
.deserialize<_$celest.DeadlineExceededError>($details);
case r'celest.core.v1.SerializationException':
throw _$celest.Serializers.instance
.deserialize<_$celest.SerializationException>($details);
case r'google_generative_ai.GenerativeAIException':
throw _$celest.Serializers.instance
.deserialize<_$error.GenerativeAIException>($details);
case r'google_generative_ai.InvalidApiKey':
throw _$celest.Serializers.instance
.deserialize<_$error.InvalidApiKey>($details);
case r'google_generative_ai.UnsupportedUserLocation':
throw _$celest.Serializers.instance
.deserialize<_$error.UnsupportedUserLocation>($details);
case r'google_generative_ai.ServerException':
throw _$celest.Serializers.instance
.deserialize<_$error.ServerException>($details);
case r'http.ClientException':
throw _$celest.Serializers.instance
.deserialize<_$exception.ClientException>($details);
default:
throw _$celest.CloudException.http(
status: $statusCode,
code: $code,
message: $message,
details: $details,
);
}
}

/// Returns a list of available models.
@_$celest.CloudFunction(
api: 'gemini',
function: 'availableModels',
)
Future<List<String>> availableModels() async {
final $response = await celest.httpClient.post(
celest.baseUri.resolve('/gemini/available-models'),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
final $body = _$convert.jsonDecode($response.body);
if ($response.statusCode != 200) {
_throwError(
$statusCode: $response.statusCode,
$body: $body,
);
}
return ($body as Iterable<Object?>).map((el) => (el as String)).toList();
}

/// Prompts the Gemini [modelName] with the given [prompt] and [parameters].
///
/// Returns the generated text.
@_$celest.CloudFunction(
api: 'gemini',
function: 'generateContent',
)
Stream<String> generateContent({
required String modelName,
required String prompt,
}) {
final $channel = celest.eventClient
.connect(celest.baseUri.resolve('/gemini/generate-content'));
$channel.sink.add({
r'modelName': modelName,
r'prompt': prompt,
});
return $channel.stream.map(($event) {
if ($event is Map<String, Object?> && $event.containsKey('@error')) {
_throwError($statusCode: -1, $body: $event);
}
return ($event as String);
});
}
}
Loading

0 comments on commit e9f04dd

Please sign in to comment.