mugib_sdk 1.0.18
mugib_sdk: ^1.0.18 copied to clipboard
Official Flutter SDK for Mugib chat sessions, voice agents, and session payload with one apiKey.
mugib_sdk #
Official unified Flutter SDK for Mugib end-user chat & voice apps.
One project API key — connect your app to a Mugib Agent:
- Chat — sessions, messages (JSON + SSE), payload per session
- Voice — real-time Mugib Voice AI
- Widget UI (read-only) — bot name, welcome message, quick replies, proactive triggers
Your app talks to the Agent — it does not configure it.
KB, MCP data sources, function-calling tools, prompts, and confirmation rules are set in Portal and handled by the backend + AI during each message.
payloadonly passes user context for one session (name, balance, plan, …).
SDK scope #
| Layer | What changes | SDK access |
|---|---|---|
| Session | Messages, payload, CSAT, conversions | mugib.chat.* ✅ main |
| Voice | Call + transcripts + session context | mugib.voice.* ✅ main |
| Widget UI | Read branding/triggers | getWidgetConfig(), getWidgetTriggers() ✅ optional |
| Tenant KB | Adds/edits KB for whole project | MugibKbService(mugib.api) ⚠️ advanced only |
| Tenant settings | Bot prompt, personality | ❌ Portal/Admin only |
What you need #
| Item | Where |
|---|---|
| Project API key | Project → Settings → API Key |
| Voice agent id (voice only) | Project → Voice Agents → numeric id |
| API base URL | https://api.mugib.com (default) |
Install #
dependencies:
mugib_sdk: ^1.0.16
flutter pub get
Requirements: Flutter 3.24+ / Dart 3.5+ · iOS & Android (voice needs microphone permissions).
Quick start — enough for most apps #
import 'package:mugib_sdk/mugib_sdk.dart';
final mugib = MugibClient(apiKey: 'YOUR_PROJECT_API_KEY');
// 1. Open session
final session = await mugib.chat.createSession();
// 2. Send messages — backend handles KB, MCP, tools, and AI replies
final reply = await session.send(
'What plan fits me?',
payload: {'name': 'Ahmed', 'plan': 'trial'},
);
print(reply.reply);
// If the bot asks "Confirm this action?" — just send yes/no:
await session.send('yes');
That is the full integration for ~90% of apps. No MCP setup, no tool config, no confirmation APIs in your code.
Chat + voice (optional) #
await MugibSdk.initialize(); // once at app startup (required for voice)
// Streaming (SSE)
await for (final event in session.sendStream('Explain Pro plan')) {
if (event is MugibStreamText) stdout.write(event.text);
}
// Voice call — same session context; verbal yes/no for tool approval works automatically
final call = mugib.voice.client(34);
await call.start(options: MugibVoiceCallOptions(
chatSessionId: session.id,
userContext: {'name': 'Ahmed'},
));
call.transcriptLines.listen((lines) {
// Ready-to-render list — partial fragments merged by the SDK
for (final t in lines) print('${t.role}: ${t.text}');
});
await call.end();
Chat API #
MugibClient.chat #
| Method | REST endpoint | Description |
|---|---|---|
createSession({pageUrl}) |
POST /api/v1/sessions |
New session (chat_…) |
listSessions() |
GET /api/v1/sessions |
Active sessions |
session(id) |
— | Bind existing session id |
MugibChatSession #
| Method | REST endpoint | Description |
|---|---|---|
send(message, {payload}) |
POST …/messages |
Blocking JSON reply |
sendStream(message, {payload}) |
POST …/messages?stream=true |
SSE token stream |
sendStreamText(…) |
same | Convenience: full string |
getHistory() |
GET …/sessions/{id} |
Message history |
reset() |
DELETE …/sessions/{id} |
Clear session |
trackConversion({goalName, …}) |
POST …/conversions |
Conversion event |
submitCsat({rating, comment}) |
POST /api/v1/csat/{id} |
1–5 star rating |
Payload #
Pass dynamic user context on every message (merged server-side):
await session.send('Check my balance', payload: {
'name': 'أحمد',
'account_id': 'ACC-9921',
'balance': '45 IQD',
});
The same payload is reused when you pass chatSessionId to a voice call.
Streaming metadata #
The final SSE event may be MugibStreamMetadata with KB sources:
await for (final event in session.sendStream('…')) {
switch (event) {
case MugibStreamText(:final text):
print(text);
case MugibStreamMetadata(:final sources):
print('Sources: ${sources.map((s) => s.title)}');
}
}
Voice API #
Voice behaviour — see voice section in docs/flutter-sdk.md for permissions, errors, and metrics.
// List agents
final agents = await mugib.voice.listAgents();
// Create call client
final call = mugib.voice.client(agents.first.id);
await call.start(); // or MugibVoiceCallOptions for payload / chatSessionId
// Analytics
final stats = await mugib.voice.analytics(34, days: 7);
Live call streams #
Bind these to your UI — the SDK handles mic, playback, reconnect, and transcript merging for you:
| Stream | Type | Use |
|---|---|---|
state |
MugibCallState |
idle / connecting / connected / listening / speaking / ended / error |
transcriptLines |
List<MugibTranscript> |
Ready-to-render transcript (partial fragments merged) |
inputLevel |
double (0.0–1.0) |
Smoothed mic level — drive a level meter so users see their mic is captured |
durationTicks |
Duration |
Elapsed call time (~1/sec) |
metrics |
MugibCallMetrics |
Time-to-first-audio + response latency |
errorEvents |
MugibVoiceError |
Structured errors (branch on .code) |
call.state.listen((s) => setState(() => _state = s));
call.transcriptLines.listen((lines) => setState(() => _lines = lines));
call.inputLevel.listen((level) => setState(() => _micLevel = level)); // 0..1 meter
call.errorEvents.listen((e) => showError(_friendly(e.code)));
call.toggleMute(); // returns the new muted state
await call.end();
A full voice-call screen — call state pill + timer, animated mic orb, input level meter, live transcript bubbles, mute, and friendly error UI — is in
example/lib/main.dart.
Echo suppression & ghost transcripts (1.0.14+) #
Mobile speakerphone can make the mic pick up the agent’s own voice; cloud STT may then show text the user never said. The SDK uses a layered, production-style stack:
| Layer | What it does |
|---|---|
| Platform AEC/NS | echoCancel, noiseSuppress, voiceChat audio session |
| Silero VAD v5 | On-device speech detection — uplink when Silero fires or mic is loud enough |
| Uplink policy | No mic send before first agent audio; stricter gates during agent playback |
| Barge-in | User can still interrupt — loud speech + VAD passes through |
| Server | Turn-taking, echo guard, and transcript filters on the Mugib bridge |
No extra code in your app — upgrade to ^1.0.16 and keep the backend updated.
1.0.16 fixes uplink blocked after the agent greeting (level meter moved but
the server received no user audio).
For best results on phones, prefer earphones in noisy environments; speaker
mode is supported with barge-in enabled.
Widget UI (read-only, optional) #
Load branding for a custom chat screen — does not modify tenant settings:
final config = await mugib.getWidgetConfig();
print(config.botName);
print(config.welcomeMessage);
print(config.quickReplies);
Proactive triggers (optional) #
Not from KB. Triggers are rules the project owner adds in Portal → Triggers
(same as projects/{id}/triggers): e.g. show a message after 30 seconds on /pricing.
final triggers = await mugib.getWidgetTriggers();
// [] when none configured — not an error
for (final t in triggers) {
print('${t.triggerType}: ${t.message}');
}
| Item | Detail |
|---|---|
| Configured in | Portal → Project → Triggers |
| REST | GET /api/v1/widget/triggers |
| When empty | { "triggers": [] } |
| Required? | No — chat & voice work without calling this |
Most Flutter apps can skip getWidgetTriggers() entirely.
Advanced chat UI (optional) #
Use only when you build a full custom chat screen like the web widget. Most apps can ignore this.
What the backend does (not your app) #
| Feature | Who configures | Who runs it | SDK needed? |
|---|---|---|---|
| MCP data search (KB, SQL, REST…) | Portal | Backend — automatic on every message | No |
| Function-calling tools (email, webhook…) | Portal | AI decides when to call; backend executes | No |
| Tool approval | Portal (requires_confirmation flag) |
Backend asks user; send("yes") or voice "yes" works |
No* |
| Human handoff | Portal (live agents) | Agent takes over in Portal; bot stops replying | poll() to show agent replies |
* confirmTool() is an optional UI helper for Confirm/Cancel buttons — same as the web widget. Text chat: send("yes") is enough. Voice: say "yes" / "no" — handled automatically.
Human handoff — show agent messages #
When a live agent takes over, bot replies stop. Poll for human-agent messages:
final poll = await session.poll(agentAfter: lastAgentCount);
if (poll.isHuman) {
for (final msg in poll.agentMessages) {
print('${msg.name}: ${msg.content}');
}
}
| Method | REST endpoint | Description |
|---|---|---|
poll({agentAfter}) |
GET …/poll |
Human-agent messages during handoff |
Tool approval buttons (optional UI) #
When a Portal tool requires confirmation, the bot asks in chat. Default: user replies send("yes") or send("no").
For Confirm/Cancel buttons instead of typed replies:
final pending = await session.pendingConfirmations();
for (final p in pending) {
// show p.summary in UI
await session.confirmTool(p.confirmationId, confirm: true);
}
| Method | REST endpoint | Description |
|---|---|---|
pendingConfirmations() |
GET …/pending-confirmations |
Tools awaiting user approval |
confirmTool(id, {confirm}) |
POST …/confirmations/{id} |
Approve / decline via button |
Advanced (tenant-wide — use with care) #
KB CRUD via API key changes the whole project KB, not one session. Prefer Portal for KB management; use only for automated sync:
final kb = MugibKbService(mugib.api);
await kb.list(search: 'pricing'); // read
// await kb.add(...) // writes tenant KB — advanced integrations only
Platform permissions (voice) #
iOS — Info.plist #
<key>NSMicrophoneUsageDescription</key>
<string>We need the microphone for voice conversations with our support agent.</string>
Android — AndroidManifest.xml #
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
minSdkVersion 23 or higher.
Error handling #
try {
await session.send('Hello');
} on MugibException catch (e) {
switch (e.code) {
case MugibErrorCode.quotaExceeded:
// upgrade plan
case MugibErrorCode.rateLimited:
// slow down
default:
print(e.message);
}
}
Voice errors use MugibVoiceException / MugibVoiceErrorCode.
Example app #
Runnable demo with a chat screen and a full voice-call screen (call controls, live transcript, mic level meter, friendly error UI):
cd sdk/flutter/mugib_sdk/example
flutter pub get
flutter run \
--dart-define=MUGIB_API_KEY=your_key \
--dart-define=MUGIB_AGENT_ID=34
Maintainers #
cd sdk/flutter/mugib_sdk
make help
make check
make update # publish to pub.dev
See PUBLISHING.md.
Links #
- Package: https://pub.dev/packages/mugib_sdk
- Integration guide: docs/flutter-sdk.md
- Voice guide: docs/voice-integration.md
- Mugib: https://mugib.com
License #
MIT — see LICENSE.