Skip to main content
The Flutter SDK provides ready-made UI templates that you can use to quickly integrate AI Voice Agents into your app without building custom UI.

Available Templates

KuralitPopupChat

A ready-to-use chat dialog template that can be opened on any page.

Features

  • Text messaging - Send and receive text messages
  • Voice input - Stream audio from microphone
  • Real-time responses - Receive streaming and final responses
  • Tool calls display - Show when agent uses tools
  • Connection status - Visual connection indicator
  • Customizable - Theme colors and widget composition

Basic Usage

import 'package:kuralit_sdk/kuralit.dart';

// Initialize SDK
Kuralit.init(KuralitConfig(
  serverUrl: 'ws://localhost:8000/ws',
  apiKey: 'demo-api-key',
  appId: 'my-app',
));

// Generate session ID
final sessionId = Kuralit.generateSessionId();

// Connect
await Kuralit.connect();

// Open popup chat
KuralitPopupChat.show(
  context,
  sessionId: sessionId,
);

With Configuration

KuralitPopupChat.show(
  context,
  sessionId: sessionId,
  config: KuralitPopupChatConfig(
    // Theme colors
    primaryColor: Colors.blue,
    backgroundColor: Colors.white,
    
    // Features
    enableAudioMode: true,  // Enable voice input
    enableToolCalls: true,   // Show tool calls
    
    // Callbacks
    onClose: () {
      print('Chat closed');
    },
  ),
);

Configuration Options

  • Theme: primaryColor, backgroundColor, messageBubbleColor
  • Features: enableAudioMode, enableToolCalls
  • Customization: messageBuilder, textInputBuilder, audioInputBuilder
  • Dialog: width, height, borderRadius
Learn more →

KuralitAgentOverlay

A full-screen animated overlay with voice-first interaction.

Features

  • Full-screen overlay - Immersive experience
  • Voice-first - Optimized for voice interaction
  • Animated UI - Golden borders and animations
  • Real-time transcription - See STT as you speak
  • Conversation history - View past messages
  • Text input option - Fallback to text input

Basic Usage

import 'package:kuralit_sdk/kuralit.dart';

// Initialize SDK
Kuralit.init(KuralitConfig(
  serverUrl: 'ws://localhost:8000/ws',
  apiKey: 'demo-api-key',
  appId: 'my-app',
));

// Generate session ID
final sessionId = Kuralit.generateSessionId();

// Connect
await Kuralit.connect();

// Open agent overlay
KuralitAgentOverlay.show(
  context,
  sessionId: sessionId,
);

When to Use

  • Voice-first apps - When voice is the primary interaction
  • Immersive experience - Full-screen focus on conversation
  • Beautiful animations - Premium UI with golden borders
  • Quick integration - No custom UI needed
Learn more →

Template Comparison

FeaturePopup ChatAgent Overlay
UI StyleDialogFull-screen overlay
Best ForQuick chat integrationVoice-first interaction
Text Input✅ Yes✅ Yes (optional)
Voice Input✅ Yes✅ Yes (primary)
AnimationsStandardPremium (golden borders)
CustomizationHighMedium
Use CaseGeneral chatVoice assistants

Customization

Custom Message Builder

KuralitPopupChat.show(
  context,
  sessionId: sessionId,
  config: KuralitPopupChatConfig(
    messageBuilder: (message) {
      // Custom message widget
      return MyCustomMessageWidget(message: message);
    },
  ),
);

Custom Input Builder

KuralitPopupChat.show(
  context,
  sessionId: sessionId,
  config: KuralitPopupChatConfig(
    textInputBuilder: (controller, isConnected, isLoading, onSend) {
      // Custom text input widget
      return MyCustomInputWidget(
        controller: controller,
        onSend: onSend,
      );
    },
  ),
);

Complete Example

import 'package:flutter/material.dart';
import 'package:kuralit_sdk/kuralit.dart';

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String? _sessionId;
  bool _isInitialized = false;

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

  void _initializeSDK() {
    Kuralit.init(KuralitConfig(
      serverUrl: 'ws://localhost:8000/ws',
      apiKey: 'demo-api-key',
      appId: 'my-app',
      debug: true,
    ));

    _sessionId = Kuralit.generateSessionId();
    _connect();

    setState(() => _isInitialized = true);
  }

  Future<void> _connect() async {
    try {
      await Kuralit.connect();
    } catch (e) {
      print('Connection failed: $e');
    }
  }

  void _openChat() {
    if (_sessionId == null) return;

    KuralitPopupChat.show(
      context,
      sessionId: _sessionId!,
      config: KuralitPopupChatConfig(
        enableAudioMode: true,
        enableToolCalls: true,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('My App')),
      body: Center(
        child: ElevatedButton(
          onPressed: _isInitialized ? _openChat : null,
          child: const Text('Open Chat'),
        ),
      ),
    );
  }
}

Best Practices

When to Use Templates

  • Quick integration - Get started fast
  • Standard UI - Templates provide good default UI
  • Prototyping - Test functionality quickly
  • Production - Templates are production-ready

When to Build Custom UI

  • Brand requirements - Need specific design
  • Complex layouts - Templates don’t fit your layout
  • Advanced features - Need features not in templates

Next Steps