mirror of https://github.com/flutter/samples.git
parent
403d3afd41
commit
5dd9fba073
@ -1,51 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PromptTextInput extends StatelessWidget {
|
||||
PromptTextInput({
|
||||
super.key,
|
||||
required this.onChanged,
|
||||
required this.onSendPressed,
|
||||
textEditingController,
|
||||
}) : _controller = textEditingController ?? TextEditingController();
|
||||
|
||||
final ValueChanged<String> onChanged;
|
||||
final VoidCallback onSendPressed;
|
||||
final TextEditingController _controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.transparent),
|
||||
borderRadius: BorderRadius.circular(40),
|
||||
color: Colors.white,
|
||||
),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width - 110,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: TextField(
|
||||
maxLines: null,
|
||||
controller: _controller,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: "Additional context...",
|
||||
),
|
||||
onChanged: (value) {
|
||||
onChanged(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
import 'package:google_generative_ai/google_generative_ai.dart';
|
||||
|
||||
import '../features/prompt/prompt_model.dart';
|
||||
|
||||
/// This code is for visual purposes only. I never actually use it when the app is running.
|
||||
|
||||
const formatting = '''
|
||||
Return the recipe as valid JSON using the following structure:
|
||||
{
|
||||
"id": \$uniqueId,
|
||||
"title": \$recipeTitle,
|
||||
"ingredients": \$ingredients,
|
||||
"description": \$description,
|
||||
"instructions": \$instructions,
|
||||
"cuisine": \$cuisineType,
|
||||
"allergens": \$allergens,
|
||||
"servings": \$servings,
|
||||
"nutritionInformation": {
|
||||
"calories": "\$calories",
|
||||
"fat": "\$fat",
|
||||
"carbohydrates": "\$carbohydrates",
|
||||
"protein": "\$protein",
|
||||
},
|
||||
}
|
||||
|
||||
uniqueId should be unique and of type String.
|
||||
title, description, cuisine, allergens, and servings should be of String type.
|
||||
ingredients and instructions should be of type List<String>.
|
||||
nutritionInformation should be of type Map<String, String>.
|
||||
''';
|
||||
|
||||
class GenerativeAIService {
|
||||
static Future<GenerateContentResponse> generateContent(
|
||||
GenerativeModel model,
|
||||
PromptData prompt,
|
||||
) async {
|
||||
final imagesParts = [];
|
||||
for (var f in prompt.images) {
|
||||
final bytes = await (f.readAsBytes());
|
||||
imagesParts.add(DataPart('image/jpeg', bytes));
|
||||
}
|
||||
|
||||
return await model.generateContent(
|
||||
[
|
||||
Content.multi([
|
||||
TextPart('''
|
||||
You are a Cat who's a chef that travels around the world a lot, and your travels inspire recipes.
|
||||
|
||||
Recommend a recipe for me based on the provided image.
|
||||
The recipe should only contain real, edible ingredients.
|
||||
If the image or images attached don't contain any food items, respond to say that you cannot recommend a recipe with inedible ingredients.
|
||||
Adhere to food safety and handling best practices like ensuring that poultry is fully cooked.
|
||||
|
||||
I'm in the mood for the following types of cuisine: ${prompt.cuisines},
|
||||
|
||||
I have the following dietary restrictions: ${prompt.selectedDietaryRestrictions}
|
||||
|
||||
Optionally also include the following ingredients: ${prompt.ingredients}
|
||||
|
||||
After providing the recipe, explain creatively why the recipe is good based on only the ingredients used in the recipe. Tell a short story of a travel experience that inspired the recipe.
|
||||
List out any ingredients that are potential allergens.
|
||||
Provide a summary of how many people the recipe will serve and the the nutritional information per serving.
|
||||
'''),
|
||||
for (var text in prompt.additionalTextInputs) TextPart(text),
|
||||
TextPart(formatting),
|
||||
...imagesParts,
|
||||
])
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
/// Matches a complete title: 0-10 whitespaces, followed by 1-6 #s, followed by the title text
|
||||
final markdownHeadingMatcher =
|
||||
RegExp(r'^ {0,10}(#{1,6})(?:[ \x09\x0b\x0c].*?)?(?:\s(#*)\s*)?$');
|
||||
|
||||
/// Matches the #s only
|
||||
final headingSyntaxMatcher = RegExp(r'(#{1,6})');
|
||||
|
||||
/// This is VERY naive. For demo purposes only.
|
||||
(bool, String) getTitleFromMarkdownRecipe(String markdown) {
|
||||
final LineSplitter splitter = LineSplitter();
|
||||
final mdCopy = markdown;
|
||||
final mdAsLines = splitter.convert(mdCopy);
|
||||
final matchingLine = mdAsLines.firstWhere((line) {
|
||||
RegExpMatch? match = markdownHeadingMatcher.firstMatch(line);
|
||||
return match != null;
|
||||
});
|
||||
RegExpMatch? match = markdownHeadingMatcher.firstMatch(matchingLine);
|
||||
if (match != null) {
|
||||
final split = matchingLine.split(headingSyntaxMatcher);
|
||||
if (split.length == 1) return (true, split.first);
|
||||
return (true, split.last);
|
||||
}
|
||||
|
||||
return (false, markdown);
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gemini_io_talk/util/markdown.dart';
|
||||
|
||||
const testMarkdown = '''
|
||||
## Potato Leek Soup
|
||||
|
||||
**Ingredients:**
|
||||
- 3 leeks
|
||||
- 3 potatoes
|
||||
- 1 onion
|
||||
- 2 cloves garlic
|
||||
- 4 cups vegetable broth
|
||||
- 1/2 cup milk
|
||||
- 1/4 cup butter
|
||||
- 1/4 cup flour
|
||||
- 1 teaspoon salt
|
||||
- 1/2 teaspoon pepper
|
||||
|
||||
**Instructions:**
|
||||
1. In a large pot or Dutch oven, heat the butter over medium heat. Add the leeks, onion, and garlic and cook until softened, about 5 minutes.
|
||||
2. Add the potatoes, vegetable broth, salt, and pepper to the pot. Bring to a boil, then reduce heat and simmer for 15 minutes, or until the potatoes are tender.
|
||||
3. In a small bowl, whisk together the milk and flour until smooth. Add to the pot and cook, stirring constantly, until the soup has thickened, about 5 minutes.
|
||||
4. Serve immediately.
|
||||
''';
|
||||
|
||||
main() {
|
||||
group('parse recipe from markdown', () {
|
||||
test('parses title', () {
|
||||
final (gotTitle, title) = getTitleFromMarkdownRecipe(testMarkdown);
|
||||
print(title);
|
||||
expect(gotTitle, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
Reference in new issue