ask_bubble_ai 1.3.6
ask_bubble_ai: ^1.3.6 copied to clipboard
A premium floating AI chat bubble widget for Flutter. Easily embed a chatbot assistant powered by Gemini, OpenAI, and Claude with custom styling, streaming, and navigation.
Ask Bubble AI #
A customizable, premium floating AI chat bubble widget for Flutter applications. Powered by Google Gemini API, OpenAI ChatGPT, and Anthropic Claude, this chatbot package lets you embed an intelligent assistant or support agent in seconds, equipped with in-app navigation triggers, active user context injection, custom styling, and built-in suggestion chips.
Key Use Cases & Keywords #
- AI Chatbot & Virtual Assistant: Elevate user experience with a floating help assistant.
- Gemini, ChatGPT & Claude integration: Connect smoothly with top LLM APIs (Google AI Studio, OpenAI, Anthropic).
- Interactive UI & Custom Styling: Fully customizable colors, headers, bubbles, and avatars.
- In-app Redirection & Navigation: Let the AI automatically suggest routes and display button triggers.
- Customer Support Agent: Ground responses using a custom knowledge base document (FAQ).
Screenshots #
| Welcome Screen | Minimized State | Chat Streaming | Actions & Markdown |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Features #
- π¬ Floating Conversation Interface: Sleek, slate-themed chat bubble that expands into a rich, modern AI assistant panel.
- β‘ Google Gemini Integration: Built on
google_generative_aifor state-of-the-art responses. - π Streaming Responses: Gemini answers stream token-by-token for a live, real-time typing experience.
- πΊοΈ In-App Navigation Actions: Empower your assistant to guide users! By responding with standard
[NAVIGATE:route_path|button_text]tags, the widget renders interactive button triggers that invokeonNavigatecallbacks. - π€ Session-Context Aware: Inject active user details (like name, role, email) and custom knowledge bases/FAQs directly into the system prompt context.
- π¨ Adaptive Design: Supports automatic dark and light mode themes to blend beautifully with your application.
- π‘ Quick Suggestions: Display clickable query suggestion chips to help guide user interactions.
- βοΈ Bubble Minimization: Minimize the floating bubble button into a compact state using a close/cancel handle to keep your UI clean.
- π Inline Markdown: AI responses render
**bold**,*italic*, and bullet lists natively inside message bubbles. - π Message Timestamps: Each bubble displays an
HH:MMtimestamp for conversation context. - π Copy to Clipboard: Long-press any message bubble to copy its text to the system clipboard.
- π¨ Full Bubble Customization: Style the floating button itself (color, icon, label, border) via
AskAiBubbleStyle.
Platform Support #
This package is written in pure Dart and Flutter with no native dependencies, meaning it supports all platforms:
| Android | iOS | Web | macOS | Windows | Linux |
|---|---|---|---|---|---|
| β | β | β | β | β | β |
Getting started #
1. Add dependency #
Add the following to your pubspec.yaml file:
dependencies:
ask_bubble_ai: ^1.3.6
Or run this command in your terminal:
flutter pub add ask_bubble_ai
2. Get an API Key #
To use this package, you need an API Key from your preferred AI provider:
- Google Gemini: Get an API Key from Google AI Studio.
- OpenAI ChatGPT: Get an API Key from OpenAI Developer Platform.
- Anthropic Claude: Get an API Key from Anthropic Console.
Warning
Do not expose your production API keys in client-side code. For development/testing, you can pass the key directly, but for production, consider securing this through a backend proxy or client-safe restrictions.
Usage #
Embed AskBubbleAi in your app. It is designed to be placed inside a Stack at the screen or shell level (e.g., above your router or homepage scaffold body).
import 'package:flutter/material.dart';
import 'package:ask_bubble_ai/ask_bubble_ai.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Ask Bubble AI Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Ask Bubble AI Demo'),
),
body: Stack(
children: [
const Center(
child: Text('Your main screen content here'),
),
Positioned(
right: 16,
bottom: 16,
child: AskBubbleAi(
apiKey: 'YOUR_GEMINI_API_KEY', // Retrieve this securely
assistantName: 'Gemini Assistant',
welcomeTitle: 'Welcome to App Support!',
welcomeSubtitle: 'Hi John! Ask me about policies, or how to navigate.',
brainDocument: '''
FAQ & Knowledge Base:
- Shipping takes 3-5 business days.
- Returns are accepted within 30 days of purchase.
- To change password, go to Settings -> Profile details.
''',
userDetails: const {
'User Name': 'John Doe',
'Role': 'Premium Member',
},
suggestions: const [
'How long does shipping take?',
'Tell me about return policy.',
'Help me update my profile.',
],
navigationRoutes: const [
{
'route': '/settings',
'description': 'User account, profile settings and password edits',
},
{
'route': '/shop',
'description': 'Product catalog, search and ordering store',
},
],
onNavigate: (routePath) {
// Handle navigation inside your application (e.g., using GoRouter or Navigator)
print('Navigate user to: $routePath');
},
),
),
],
),
);
}
}
Navigation Capabilities #
The widget has a built-in parser for route navigation. If the Gemini assistant decides that a user needs to go to a screen, it will format a token like:
[NAVIGATE:route_path|button_text]
This token is automatically parsed from the text, and a stylish button is displayed inside the message bubble:
"You can manage your account in settings: [NAVIGATE:/settings|Open Settings]"
When clicked, the button triggers the onNavigate function with /settings as the argument.
Use Case Examples #
AskBubbleAi is highly customizable and fits into various application domains. Here is how you can configure it for different use cases:
π E-Commerce Applications #
Provide your store policies and shopping routes so the AI can help customers track orders, understand return guidelines, and navigate the store:
AskBubbleAi(
apiKey: 'GEMINI_API_KEY',
assistantName: 'ShopBot',
welcomeTitle: 'Store Assistant',
welcomeSubtitle: 'Hi! Ask me about returns, shipping, or view your cart.',
brainDocument: '''
Store Policy Document:
- Standard shipping takes 3 to 5 business days.
- Items can be returned within 30 days of delivery.
- Current promotions: 10% off on electronics with code SAVE10.
''',
userDetails: const {
'Customer Name': 'John Doe',
'Cart Item Count': '3 Items',
'Last Order ID': '#88741',
},
suggestions: const [
'What is the return policy?',
'Where is my last order?',
'Show my cart details',
],
navigationRoutes: const [
{'route': '/products', 'description': 'Product catalog and shop page'},
{'route': '/cart', 'description': 'Shopping cart details and checkout page'},
{'route': '/orders', 'description': 'List of customer orders and tracking status'},
],
onNavigate: (route) => Navigator.pushNamed(context, route),
)
πΌ Management & HR Portals #
Provide your company handbook, employee details, and internal pages so the AI can help team members apply for leaves, view dashboards, or update profiles:
AskBubbleAi(
apiKey: 'GEMINI_API_KEY',
assistantName: 'Office Concierge',
welcomeTitle: 'Employee Support',
welcomeSubtitle: 'Hi Jane, how can I assist you with your tasks today?',
brainDocument: '''
Employee Portal Guide:
- Annual leaves must be requested 2 weeks in advance.
- Timesheets are due every Friday by 5 PM.
- Expense claims are processed on the 1st of every month.
''',
userDetails: const {
'Employee Name': 'Jane Smith',
'Department': 'Engineering',
'Manager': 'David K.',
},
suggestions: const [
'How do I request leave?',
'When are timesheets due?',
'Open my dashboard',
],
navigationRoutes: const [
{'route': '/dashboard', 'description': 'Employee work and project metrics'},
{'route': '/leave', 'description': 'Time off requests, annual leaves, calendar'},
{'route': '/profile', 'description': 'Personal employee account and work details'},
],
onNavigate: (route) => myAppRouter.push(route),
)
Configuration Properties #
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey |
String |
Yes | - | API Key for the selected provider (Gemini, OpenAI, or Claude). |
provider |
AskAiProvider |
No | AskAiProvider.gemini |
The AI service provider to use. Can be AskAiProvider.gemini, AskAiProvider.openAi, or AskAiProvider.claude. |
assistantName |
String |
No | 'AI Assistant' |
The name of the AI assistant displayed in the chat interface. |
modelName |
String? |
No | null |
Custom AI model override identifier. If null, automatically falls back to: gemini-2.5-flash (Gemini), gpt-4o-mini (OpenAI), or claude-3-5-haiku-20241022 (Claude). |
userDetails |
Map<String, String>? |
No | null |
Contextual details of the active user session injected into the prompt. |
brainDocument |
String |
No | AskAiConstants.defaultBrainDocument |
Document or FAQ context used to ground model answers. |
suggestions |
List<String> |
No | AskAiConstants.suggestions |
Frequently asked questions or suggestion chips shown on the initial welcome state. |
navigationRoutes |
List<Map<String, String>> |
No | [] |
List of routes (route and description) the AI is allowed to trigger. |
onNavigate |
Function(String)? |
No | null |
Callback invoked when a navigation button trigger is tapped. |
welcomeTitle |
String |
No | 'Welcome!' |
Header text shown when the panel is first opened. |
welcomeSubtitle |
String |
No | 'Hi, I am your AI assistant...' |
Subheader description shown on the welcome state. |
systemInstruction |
String? |
No | null |
Custom system instructions override. If null, a system instruction is dynamically generated using the other configuration options. |
panelStyle |
AskAiPanelStyle? |
No | null |
Custom styling for the panel window, including background color, border color, primary brand color, height, and width. |
headerStyle |
AskAiHeaderStyle? |
No | null |
Custom styling for the panel header, including background color, title/subtitle styles, icon colors, and bot avatar customization. |
bubbleStyle |
AskAiBubbleStyle? |
No | null |
Custom styling for the floating bubble button, including background color, icon, label color, and border radius. |
initiallyOpen |
bool |
No | false |
Whether the chat panel should start in the open state. |
showTimestamps |
bool |
No | true |
Whether to display HH:MM timestamps beneath each message bubble. |
maxTokens |
int |
No | 2048 |
Maximum number of response tokens for any provider. |
AskAiHeaderStyle β Avatar options
| Field | Type | Description |
|---|---|---|
avatarIcon |
IconData? |
A Material icon shown in the avatar circle (e.g. Icons.support_agent_rounded). |
avatarWidget |
Widget? |
A fully custom widget used as the avatar β takes precedence over avatarIcon when set. Pass any widget: Image.asset, Image.network, a ClipOval logo, or a Stack. |
avatarIconColor |
Color? |
Color of the avatar icon (also used for the avatar border when no custom color is set). |
avatarBackgroundColor |
Color? |
Fill color of the circular avatar container. |
π¨ Custom Styling Example #
You can customize the chat window panel, header, and the floating bubble button to align with your application branding:
AskBubbleAi(
apiKey: 'YOUR_API_KEY',
bubbleStyle: const AskAiBubbleStyle(
backgroundColor: Color(0xFF6366F1), // Indigo bubble
icon: Icons.support_agent_rounded,
iconColor: Colors.white,
labelColor: Colors.white,
borderColor: Color(0xFF818CF8),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
panelStyle: const AskAiPanelStyle(
backgroundColor: Color(0xFF1E293B), // Slate background
borderColor: Color(0xFF475569),
primaryColor: Color(0xFF6366F1), // Indigo brand color
borderRadius: BorderRadius.all(Radius.circular(24)),
width: 380,
height: 560,
),
headerStyle: const AskAiHeaderStyle(
backgroundColor: Color(0xFF0F172A), // Dark header Bg
titleStyle: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w800,
),
subtitleStyle: TextStyle(
color: Colors.white70,
fontSize: 11,
),
iconColor: Colors.white,
avatarBackgroundColor: Color(0xFF312E81),
avatarIcon: Icons.support_agent_rounded,
avatarIconColor: Color(0xFF818CF8),
),
)
βοΈ Controlling Tokens & Opening State #
AskBubbleAi(
apiKey: 'YOUR_API_KEY',
initiallyOpen: true, // Panel opens automatically
showTimestamps: false, // Hide message timestamps
maxTokens: 1024, // Limit response length
)
πΌοΈ Avatar β Icon or Custom Logo #
Use avatarIcon for any Material icon, or avatarWidget for a fully custom widget (image, logo, etc.). avatarWidget takes precedence when both are provided.
Option 1 β Material icon (e.g. support agent):
headerStyle: const AskAiHeaderStyle(
avatarIcon: Icons.support_agent_rounded,
avatarIconColor: Colors.white,
avatarBackgroundColor: Color(0xFF1C4079),
)
Option 2 β Custom image/logo:
headerStyle: AskAiHeaderStyle(
avatarBackgroundColor: Colors.white,
avatarWidget: ClipOval(
child: Image.asset(
'assets/logo.png',
width: 32,
height: 32,
fit: BoxFit.cover,
),
),
)
Option 3 β Icon + logo badge (Stack):
headerStyle: AskAiHeaderStyle(
avatarBackgroundColor: const Color(0xFF1C4079),
avatarWidget: Stack(
alignment: Alignment.center,
children: [
const Icon(Icons.support_agent_rounded, color: Colors.white, size: 18),
Positioned(
bottom: 0,
right: 0,
child: Image.asset('assets/logo_badge.png', width: 12, height: 12),
),
],
),
)
License #
This project is licensed under the MIT License - see the LICENSE file for details.



