Skip to content

Commit ea347a0

Browse files
committed
chore(repo): Update examples for 0.2.0
1 parent 1365d37 commit ea347a0

File tree

52 files changed

+789
-591
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+789
-591
lines changed

examples/gemini/celest/functions/gemini.dart

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// Cloud functions are top-level Dart functions defined in the `functions/`
22
// folder of your Celest project.
33

4+
import 'dart:convert';
5+
46
import 'package:celest/celest.dart';
5-
import 'package:celest_backend/models.dart';
67
import 'package:google_generative_ai/google_generative_ai.dart';
78

89
import '../resources.dart';
@@ -24,8 +25,7 @@ const _availableModels = [
2425
Future<String> generateContent({
2526
required String modelName,
2627
required String prompt,
27-
ModelParameters parameters = const ModelParameters(),
28-
@env.geminiApiKey required String apiKey,
28+
@Env.geminiApiKey required String apiKey,
2929
}) async {
3030
if (!_availableModels.contains(modelName)) {
3131
throw BadRequestException('Invalid model: $modelName');
@@ -35,19 +35,52 @@ Future<String> generateContent({
3535
final request = [
3636
Content.text(prompt),
3737
];
38-
final response = await model.generateContent(
39-
request,
40-
generationConfig: GenerationConfig(
41-
maxOutputTokens: parameters.maxTokens,
42-
temperature: parameters.temperature,
43-
),
44-
);
38+
print('Sending prompt: $prompt');
39+
40+
final response = await model.generateContent(request);
41+
print('Got response: ${_prettyJson(response.toJson())}');
4542

4643
switch (response.text) {
4744
case final text?:
48-
print('Gemini response: $text');
45+
print('Selected answer: $text');
4946
return text;
5047
case _:
5148
throw InternalServerException('Failed to generate content');
5249
}
5350
}
51+
52+
extension on GenerateContentResponse {
53+
Map<String, Object?> toJson() => {
54+
'promptFeedback': {
55+
'blockReason': promptFeedback?.blockReason?.name,
56+
'blockReasonMessage': promptFeedback?.blockReasonMessage,
57+
'safetyRatings': [
58+
for (final rating
59+
in promptFeedback?.safetyRatings ?? <SafetyRating>[])
60+
{
61+
'category': rating.category.name,
62+
'probability': rating.probability.name,
63+
},
64+
],
65+
},
66+
'candidates': [
67+
for (final candidate in candidates)
68+
{
69+
'content': candidate.content.toJson(),
70+
'safetyRatings': [
71+
for (final rating
72+
in candidate.safetyRatings ?? <SafetyRating>[])
73+
{
74+
'category': rating.category.name,
75+
'probability': rating.probability.name,
76+
},
77+
],
78+
'finishReason': candidate.finishReason?.name,
79+
'finishMessage': candidate.finishMessage,
80+
},
81+
],
82+
};
83+
}
84+
85+
String _prettyJson(Object? json) =>
86+
const JsonEncoder.withIndent(' ').convert(json);

examples/gemini/celest/lib/client.dart

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,60 @@
22
// it can be checked into version control.
33
// ignore_for_file: type=lint, unused_local_variable, unnecessary_cast, unnecessary_import
44

5-
library;
5+
library; // ignore_for_file: no_leading_underscores_for_library_prefixes
66

7-
import 'dart:io';
7+
import 'dart:io' as _$io;
88

9-
import 'package:celest/celest.dart';
109
import 'package:celest_core/src/util/globals.dart';
11-
import 'package:http/http.dart' as http;
10+
import 'package:http/http.dart' as _$http;
1211

1312
import 'src/client/functions.dart';
1413
import 'src/client/serializers.dart';
1514

1615
final Celest celest = Celest();
1716

17+
enum CelestEnvironment {
18+
local;
19+
20+
Uri get baseUri => switch (this) {
21+
local => kIsWeb || !_$io.Platform.isAndroid
22+
? Uri.parse('http://localhost:7781')
23+
: Uri.parse('http://10.0.2.2:7781'),
24+
};
25+
}
26+
1827
class Celest {
19-
late http.Client httpClient = http.Client();
28+
var _initialized = false;
29+
30+
late CelestEnvironment _currentEnvironment;
31+
32+
late _$http.Client httpClient = _$http.Client();
33+
34+
late Uri _baseUri;
35+
36+
final _functions = CelestFunctions();
37+
38+
T _checkInitialized<T>(T Function() value) {
39+
if (!_initialized) {
40+
throw StateError(
41+
'Celest has not been initialized. Make sure to call `celest.init()` at the start of your `main` method.');
42+
}
43+
return value();
44+
}
45+
46+
CelestEnvironment get currentEnvironment =>
47+
_checkInitialized(() => _currentEnvironment);
2048

21-
late final Uri baseUri = kIsWeb || !Platform.isAndroid
22-
? Uri.parse('http://localhost:7777')
23-
: Uri.parse('http://10.0.2.2:7777');
49+
Uri get baseUri => _checkInitialized(() => _baseUri);
2450

25-
final functions = CelestFunctions();
51+
CelestFunctions get functions => _checkInitialized(() => _functions);
2652

27-
void init() {
28-
Serializers.instance.put(const ModelParametersSerializer());
53+
void init({CelestEnvironment environment = CelestEnvironment.local}) {
54+
_currentEnvironment = environment;
55+
_baseUri = environment.baseUri;
56+
if (!_initialized) {
57+
initSerializers();
58+
}
59+
_initialized = true;
2960
}
3061
}

examples/gemini/celest/lib/exceptions.dart

Lines changed: 0 additions & 2 deletions
This file was deleted.

examples/gemini/celest/lib/models.dart

Lines changed: 0 additions & 13 deletions
This file was deleted.

examples/gemini/celest/lib/src/client/functions.dart

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
// it can be checked into version control.
33
// ignore_for_file: type=lint, unused_local_variable, unnecessary_cast, unnecessary_import
44

5-
library;
5+
library; // ignore_for_file: no_leading_underscores_for_library_prefixes
66

7-
import 'dart:convert';
7+
import 'dart:convert' as _$convert;
88

99
import 'package:celest/celest.dart';
10-
import 'package:celest_backend/models.dart';
1110
import 'package:celest_core/src/exception/cloud_exception.dart';
11+
import 'package:celest_core/src/exception/serialization_exception.dart';
12+
import 'package:google_generative_ai/src/error.dart' as _$error;
13+
import 'package:http/src/exception.dart' as _$exception;
1214

1315
import '../../client.dart';
1416

@@ -17,18 +19,10 @@ class CelestFunctions {
1719
}
1820

1921
class CelestFunctionsGemini {
20-
/// Returns a list of available models.
21-
Future<List<String>> availableModels() async {
22-
final $response = await celest.httpClient.post(
23-
celest.baseUri.resolve('/gemini/available-models'),
24-
headers: const {'Content-Type': 'application/json; charset=utf-8'},
25-
);
26-
final $body = (jsonDecode($response.body) as Map<String, Object?>);
27-
if ($response.statusCode == 200) {
28-
return ($body['response'] as Iterable<Object?>)
29-
.map((el) => (el as String))
30-
.toList();
31-
}
22+
Never _throwError({
23+
required int $statusCode,
24+
required Map<String, Object?> $body,
25+
}) {
3226
final $error = ($body['error'] as Map<String, Object?>);
3327
final $code = ($error['code'] as String);
3428
final $details = ($error['details'] as Map<String, Object?>?);
@@ -38,8 +32,25 @@ class CelestFunctionsGemini {
3832
case r'InternalServerException':
3933
throw Serializers.instance
4034
.deserialize<InternalServerException>($details);
35+
case r'SerializationException':
36+
throw Serializers.instance
37+
.deserialize<SerializationException>($details);
38+
case r'GenerativeAIException':
39+
throw Serializers.instance
40+
.deserialize<_$error.GenerativeAIException>($details);
41+
case r'InvalidApiKey':
42+
throw Serializers.instance.deserialize<_$error.InvalidApiKey>($details);
43+
case r'UnsupportedUserLocation':
44+
throw Serializers.instance
45+
.deserialize<_$error.UnsupportedUserLocation>($details);
46+
case r'ServerException':
47+
throw Serializers.instance
48+
.deserialize<_$error.ServerException>($details);
49+
case r'ClientException':
50+
throw Serializers.instance
51+
.deserialize<_$exception.ClientException>($details);
4152
case _:
42-
switch ($response.statusCode) {
53+
switch ($statusCode) {
4354
case 400:
4455
throw BadRequestException($code);
4556
case _:
@@ -48,44 +59,48 @@ class CelestFunctionsGemini {
4859
}
4960
}
5061

62+
/// Returns a list of available models.
63+
Future<List<String>> availableModels() async {
64+
final $response = await celest.httpClient.post(
65+
celest.baseUri.resolve('/gemini/available-models'),
66+
headers: const {'Content-Type': 'application/json; charset=utf-8'},
67+
);
68+
final $body =
69+
(_$convert.jsonDecode($response.body) as Map<String, Object?>);
70+
if ($response.statusCode != 200) {
71+
_throwError(
72+
$statusCode: $response.statusCode,
73+
$body: $body,
74+
);
75+
}
76+
return ($body['response'] as Iterable<Object?>)
77+
.map((el) => (el as String))
78+
.toList();
79+
}
80+
5181
/// Prompts the Gemini [modelName] with the given [prompt] and [parameters].
5282
///
5383
/// Returns the generated text.
5484
Future<String> generateContent({
5585
required String modelName,
5686
required String prompt,
57-
ModelParameters parameters = const ModelParameters(),
5887
}) async {
5988
final $response = await celest.httpClient.post(
6089
celest.baseUri.resolve('/gemini/generate-content'),
6190
headers: const {'Content-Type': 'application/json; charset=utf-8'},
62-
body: jsonEncode({
91+
body: _$convert.jsonEncode({
6392
r'modelName': modelName,
6493
r'prompt': prompt,
65-
r'parameters':
66-
Serializers.instance.serialize<ModelParameters>(parameters),
6794
}),
6895
);
69-
final $body = (jsonDecode($response.body) as Map<String, Object?>);
70-
if ($response.statusCode == 200) {
71-
return ($body['response'] as String);
72-
}
73-
final $error = ($body['error'] as Map<String, Object?>);
74-
final $code = ($error['code'] as String);
75-
final $details = ($error['details'] as Map<String, Object?>?);
76-
switch ($code) {
77-
case r'BadRequestException':
78-
throw Serializers.instance.deserialize<BadRequestException>($details);
79-
case r'InternalServerException':
80-
throw Serializers.instance
81-
.deserialize<InternalServerException>($details);
82-
case _:
83-
switch ($response.statusCode) {
84-
case 400:
85-
throw BadRequestException($code);
86-
case _:
87-
throw InternalServerException($code);
88-
}
96+
final $body =
97+
(_$convert.jsonDecode($response.body) as Map<String, Object?>);
98+
if ($response.statusCode != 200) {
99+
_throwError(
100+
$statusCode: $response.statusCode,
101+
$body: $body,
102+
);
89103
}
104+
return ($body['response'] as String);
90105
}
91106
}

0 commit comments

Comments
 (0)