ringg_flutter 0.1.5 copy "ringg_flutter: ^0.1.5" to clipboard
ringg_flutter: ^0.1.5 copied to clipboard

Ringg AI widget for Flutter — drop-in widget and headless controller for voice/text AI agents.

ringg_flutter #

⚠️ Alpha / pre-release. This package is early and under active development — expect rough edges, occasional bugs, and breaking changes between versions. Pin an exact version if you need stability, and please report anything you hit. See Known issues below.

Embeddable chat + voice-call widget for Ringg AI agents — the Flutter implementation. Drop RinggWidget over your app for text chat, voice calls, interactive components (forms, calendars, quick replies, Block Kit) and a post-call feedback screen.

Install #

dependencies:
  ringg_flutter: ^0.1.5

Then flutter pub get. Requires Dart ≥ 3.6 · Flutter ≥ 3.27.

Platform setup (required for voice) #

Voice calls need microphone + audio permissions.

iOS — ios/Runner/Info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>Voice calls use the microphone.</string>
<key>UIBackgroundModes</key>
<array><string>audio</string></array>

Android — android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

Integrate in 3 steps #

Create a transport, build a controller with your agent config, then mount the widget. Hold the transport + controller in a State so you can dispose them.

1 · Get your credentials #

From the Ringg dashboard you need your agent id and a bearer authorization token. That's it — endpoints are built in (production by default).

2 · Wire up a controller + widget #

import 'package:flutter/material.dart';
import 'package:ringg_flutter/ringg_flutter.dart';

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

  @override
  State<RinggSupport> createState() => _RinggSupportState();
}

class _RinggSupportState extends State<RinggSupport> {
  late final LiveKitTransport _transport;
  late final RinggWidgetController _controller;

  @override
  void initState() {
    super.initState();
    _transport = createLiveKitTransport();
    _controller = RinggWidgetController(
      const RinggWidgetConfig(
        agentId: '<your-agent-id>',
        authorization: 'Bearer <your-token>',
        title: 'Support',
        description: 'How can we help?',
        defaultTab: MediaType.text, // or MediaType.voice
      ),
      // Endpoints default to production; no URLs to configure.
      ControllerPorts(transport: _transport.transport),
    );
  }

  @override
  void dispose() {
    _controller.destroy();
    _transport.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => RinggWidget(
        controller: _controller,
        transport: _transport, // enables the in-call audio visualizer
      );
}

3 · Mount it over your app #

RinggWidget places its own floating trigger + panel, so give it the full screen on top of your content:

Stack(
  children: const [
    YourApp(),
    RinggSupport(),
  ],
)

Tap the trigger → the chat/voice panel opens. That's the whole integration.

Native platforms & the Origin header. Browsers attach an Origin automatically and the backend allow-lists an agent's callers by that value; native HTTP sends nothing. You don't configure this — the package sends <platform>://<bundleId>, read from the running app:

Platform Origin
Android android://<applicationId>
iOS ios://<bundleId>
macOS / Windows / Linux macos://…, windows://…, linux://…

Add those to the agent's Allowed clients (Agent → Webcall → Install & domains) or the call is refused with "Client '…' is not allowed to initiate webcall". Ids differ per platform and per flavor (.debug, .staging), so each build you ship needs its own entry — the value sent is logged on a refused call, ready to paste.

To pin one string instead — a single canonical value across flavors, say — set it in config; it wins over the derived one:

RinggWidgetConfig(
  agentId: '<your-agent-id>',
  clientOrigin: 'android://com.yourcompany.yourapp',
);

Supplying your own ControllerPorts(httpClient: …) opts out of the default; wrap it to keep the header: appOriginHttpClient(inner: yourClient).

Hybrid WebView runtimes (capacitor://localhost, ionic://localhost, file://) are identical for every app on that runtime — allowing one admits all of them.

Configuration #

RinggWidgetConfig — only agentId is required; everything else is optional:

Field Type Purpose
agentId String your Ringg agent (required)
authorization String? bearer token for your account
clientOrigin String? caller identity sent as Origin (android://com.example.app) — must be in the agent's Allowed clients
title / description String? panel header text
defaultTab MediaType? open in text or voice
hideTabSelector bool? hide the text/voice switch
defaultExpanded bool? open the panel on load
bypassStartScreen bool? jump straight into a call
variables Map<String, Object>? values for {{placeholders}} in agent prompts
logoUrl / theme / widgetPosition / legalDisclaimer / buttons branding, placement & styling

Example app #

A runnable example ships in the Example tab (the example/ directory) — see its README.md for how to run it.

Platform support #

Android · iOS · macOS · Windows · Linux. Web is not supported.

Known issues #

This is an alpha — here's what to watch for:

  • Breaking changes between releases. APIs may shift while pre-1.0; pin an exact version if you need stability.
  • iOS simulators (26.x) have no call audio. The simulator exposes no mic or playout device, so you won't hear the agent or be able to unmute — an OS-simulator + upstream realtime-SDK limitation, not fixable app-side. The widget degrades to a listen-only attempt. Test voice on a real device, an Android emulator, or macOS. (Apple refs: forums 738346, 803364.)
  • Voice on Android emulators can fail to connect. Emulator networking often can't establish the media connection; text chat works, but voice needs a real device.
  • Expect bugs. If something misbehaves, please file an issue with repro steps.
0
likes
140
points
113
downloads

Documentation

API reference

Publisher

verified publisherringg.ai

Weekly Downloads

Ringg AI widget for Flutter — drop-in widget and headless controller for voice/text AI agents.

Homepage

License

MIT (license)

Dependencies

audioplayers, flutter, flutter_markdown_plus, flutter_svg, http, livekit_client, markdown, package_info_plus, url_launcher

More

Packages that depend on ringg_flutter