flutter_ai_kit 1.0.2 copy "flutter_ai_kit: ^1.0.2" to clipboard
flutter_ai_kit: ^1.0.2 copied to clipboard

A comprehensive Flutter package for integrating AI services like OpenAI, Google Gemini, and HuggingFace. Features include chat interfaces, image generation, and text processing with beautiful UI components.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_ai_kit/flutter_ai_kit.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter AI Kit Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      darkTheme: ThemeData.dark(useMaterial3: true).copyWith(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.dark,
        ),
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  AIConfig? _openAIConfig;
  AIConfig? _geminiConfig;
  AIConfig? _huggingFaceConfig;
  bool _isLoading = true;

  AIKitTheme _theme = const AIKitTheme();

  final _generationOptions = const GenerationOptions(
    temperature: 0.7,
    maxTokens: 1000,
    topP: 1.0,
    presencePenalty: 0.0,
    frequencyPenalty: 0.0,
  );

  @override
  void initState() {
    super.initState();
    _loadApiKeys();
  }

  Future<void> _loadApiKeys() async {
    setState(() => _isLoading = true);
    try {
      final prefs = await SharedPreferences.getInstance();

      final openaiKey = prefs.getString('openai_key');
      final geminiKey = prefs.getString('gemini_key');
      final huggingfaceKey = prefs.getString('huggingface_key');

      setState(() {
        // Only set configs if keys are valid (not null, not empty, and don't contain error messages)
        if (openaiKey != null &&
            openaiKey.isNotEmpty &&
            !openaiKey.contains('Exception') &&
            !openaiKey.startsWith('your-')) {
          _openAIConfig = AIConfig.openAI(
            apiKey: openaiKey,
            modelName: 'gpt-3.5-turbo',
          );
        } else {
          _openAIConfig = null;
        }

        if (geminiKey != null &&
            geminiKey.isNotEmpty &&
            !geminiKey.contains('Exception') &&
            !geminiKey.startsWith('your-')) {
          _geminiConfig = AIConfig.gemini(
            apiKey: geminiKey,
            modelName: 'gemini-pro',
          );
        } else {
          _geminiConfig = null;
        }

        if (huggingfaceKey != null &&
            huggingfaceKey.isNotEmpty &&
            !huggingfaceKey.contains('Exception') &&
            !huggingfaceKey.startsWith('your-')) {
          _huggingFaceConfig = AIConfig.huggingFace(
            apiKey: huggingfaceKey,
            modelName: 'mistral',
          );
        } else {
          _huggingFaceConfig = null;
        }
      });
    } catch (e) {
      print('Error loading API keys: $e');
      setState(() {
        _openAIConfig = null;
        _geminiConfig = null;
        _huggingFaceConfig = null;
      });
    } finally {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _saveApiKey(String key, String value) async {
    if (value.isEmpty ||
        value.contains('Exception') ||
        value.startsWith('your-')) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Please enter a valid API key'),
          backgroundColor: Colors.red,
        ),
      );
      return;
    }

    setState(() => _isLoading = true);
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString(key, value);
      await _loadApiKeys();

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
              '${key.split('_')[0].toUpperCase()} API key saved successfully'),
          backgroundColor: Colors.green,
        ),
      );
    } catch (e) {
      print('Error saving API key: $e');
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Failed to save API key'),
          backgroundColor: Colors.red,
        ),
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  void _showApiKeyDialog(String provider) {
    final controller = TextEditingController();
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('Set $provider API Key'),
        content: TextField(
          controller: controller,
          decoration: InputDecoration(
            hintText: 'Enter your $provider API key',
          ),
          obscureText: true,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () {
              _saveApiKey('${provider.toLowerCase()}_key', controller.text);
              Navigator.pop(context);
            },
            child: const Text('Save'),
          ),
        ],
      ),
    );
  }

  Widget _buildMissingApiKeyMessage(String provider) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            'No $provider API key found',
            style: Theme.of(context).textTheme.titleMedium,
          ),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: () => _showApiKeyDialog(provider),
            child: Text('Set $provider API Key'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return const Scaffold(
        body: Center(
          child: CircularProgressIndicator(),
        ),
      );
    }

    _theme = const AIKitTheme();

    return DefaultTabController(
      length: 4,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter AI Kit Demo'),
          actions: [
            PopupMenuButton<String>(
              onSelected: _showApiKeyDialog,
              itemBuilder: (context) => [
                const PopupMenuItem(
                  value: 'openai',
                  child: Text('Set OpenAI Key'),
                ),
                const PopupMenuItem(
                  value: 'gemini',
                  child: Text('Set Gemini Key'),
                ),
                const PopupMenuItem(
                  value: 'huggingface',
                  child: Text('Set HuggingFace Key'),
                ),
              ],
            ),
          ],
          bottom: const TabBar(
            padding: EdgeInsets.zero,
            tabs: [
              Tab(text: 'OpenAI Chat'),
              Tab(text: 'Gemini Chat'),
              Tab(text: 'Image Gen'),
              Tab(text: 'Text Process'),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            // OpenAI Chat Tab
            _openAIConfig == null
                ? _buildMissingApiKeyMessage('OpenAI')
                : AIChatWidget(
                    config: _openAIConfig!,
                    theme: _theme,
                    options: _generationOptions,
                    placeholder: 'Chat with OpenAI...',
                    onMessageSent: (message) {
                      print('OpenAI - Sent: ${message.content}');
                    },
                    onMessageReceived: (message) {
                      print('OpenAI - Received: ${message.content}');
                    },
                  ),

            // Gemini Chat Tab
            _geminiConfig == null
                ? _buildMissingApiKeyMessage('Gemini')
                : AIChatWidget(
                    config: _geminiConfig!,
                    theme: _theme,
                    options: _generationOptions.copyWith(
                      temperature: 0.9,
                      additionalOptions: {
                        'candidate_count': 1,
                      },
                    ),
                    placeholder: 'Chat with Gemini...',
                    onMessageSent: (message) {
                      print('Gemini - Sent: ${message.content}');
                    },
                    onMessageReceived: (message) {
                      print('Gemini - Received: ${message.content}');
                    },
                  ),

            // Image Generation Tab
            _openAIConfig == null
                ? _buildMissingApiKeyMessage('OpenAI')
                : Column(
                    children: [
                      Expanded(
                        child: ImageGenerationWidget(
                          config: _openAIConfig!,
                          theme: _theme,
                          placeholder:
                              'Describe the image you want to generate...',
                          parameters: {
                            'size': '1024x1024',
                            'n': 1,
                            'model': 'dall-e-3',
                            'quality': 'standard',
                            'style': 'vivid',
                          },
                          onImageGenerated: (imageUrl) {
                            print('Generated image: $imageUrl');
                            ScaffoldMessenger.of(context).showSnackBar(
                              const SnackBar(
                                content: Text('Image generated successfully!'),
                              ),
                            );
                          },
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                          'Using OpenAI DALL-E for image generation',
                          style: Theme.of(context).textTheme.bodySmall,
                        ),
                      ),
                    ],
                  ),

            // Text Processing Tab
            _huggingFaceConfig == null
                ? _buildMissingApiKeyMessage('HuggingFace')
                : Column(
                    children: [
                      Expanded(
                        child: TextProcessingWidget(
                          config: _huggingFaceConfig!,
                          theme: _theme,
                          options: _generationOptions,
                          systemPrompt:
                              '''You are a helpful assistant that helps improve text. Please help format, correct grammar, and improve the following text while maintaining its original meaning.''',
                          placeholder: 'Enter text to process...',
                          useMarkdown: true,
                          onProcessingComplete: (result) {
                            print('Processed text: $result');
                          },
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                          'Using HuggingFace for text processing',
                          style: Theme.of(context).textTheme.bodySmall,
                        ),
                      ),
                    ],
                  ),
          ],
        ),
      ),
    );
  }
}
3
likes
120
points
46
downloads
screenshot

Publisher

unverified uploader

Weekly Downloads

A comprehensive Flutter package for integrating AI services like OpenAI, Google Gemini, and HuggingFace. Features include chat interfaces, image generation, and text processing with beautiful UI components.

Repository (GitHub)
View/report issues
Contributing

Topics

#ai #chatbot #openai #gemini #huggingface

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

cached_network_image, flutter, flutter_markdown, google_fonts, http, provider, shared_preferences, timeago

More

Packages that depend on flutter_ai_kit