embed_flutter 0.2.0
embed_flutter: ^0.2.0 copied to clipboard
A powerful Flutter SDK that provides a powerful voice-enabled AI-agent functionality with real-time widget tree monitoring for screen context fetching and realtime voice communication.
Changelog #
0.2.0 #
Native-parity release: the Flutter SDK's config wiring, call/agent modes, back navigation, and widget UX brought in line with the Android and React Native SDKs and the revrag-core wire contract. Verified live on a physical device.
Breaking changes — migration required #
- Multi-agent (
flowName) support removed — React / React Native parity. One integration is one agent, so the per-flow scoping is gone:embedInitialize,EmbedProviderandembedEvent(andembedTrack*) no longer take aflowName.EmbedWidget.enabledRouteschanges shape fromMap<String, List<String>>(flow → routes) to a flatList<String>:enabledRoutes: {'main': ['home','account']}→enabledRoutes: ['home','account'].EmbedWidget.groupContinuity/groupDelays(flow-keyed maps) become the singlecontinuity:/buttonDelay:.EmbedRouteManager's flow surface (currentFlow,catalogFlow,getFlowForRoute,setCurrentFlow,flowRoutes,continuityForFlow/delayMsForFlow/delayPolicyForFlow) is replaced by a flat API (activeGroup,isRouteEnabled,groupForRoute,enabledRoutes,continuity,delayMs,delayPolicy). Config, cache and event scoping collapse to one agent; existing on-device caches stay valid (the default scope is unchanged). Multi-agent apps must split into separate integrations.
EmbedWidgetapiKey/embedUrl/primaryColor/groupInsetsremoved (and theEmbedButtonInsettype). Credentials come fromembedInitialize; the FAB position (widget_config.position) and colors (widget_config.colorPalette) come from the backend — the host no longer overrides them on the widget. Use a per-widget key only viaembedInitialize.EmbedWidget/EmbedProviderrightPadding/bottomPaddingremoved. FAB position is now driven solely by the backendwidget_config(right_padding/bottom_padding/widget_position) — the host no longer overrides it in code. Set the position from the dashboard instead; remove the two params from yourEmbedWidgetcall.embedInitializeis now the single, all-named intake —embedInitialize(apiKey: …, appVersion: …, embedUrl: …).apiKeymoved from positional to a required named parameter, andappVersionis now required (embedSetAppVersion()and thepackage_info_plusauto-derivation are gone).EmbedProviderremoved. It only forwardedapiKey/embedUrl/appVersionintoembedInitializeand mounted anEmbedWidget; withembedInitializeas the single intake it was a redundant wrapper. CallembedInitialize+ wrap withEmbedWidgetdirectly.- Server-driven panels/cards now render only in
workflowmode. A call the user starts from the FAB (or the inactivity auto-trigger) is a co-pilot call and drops inbound panel frames. To keep panels, start the call from host code withEmbedWidget.startCall(agentTriggerMode: AgentTriggerMode.WORKFLOW). other_dataflags removed — no peer SDK ever read them:widget_tree_snapshot_enabledandscreen_capture_enabled(widget-tree snapshot sends now gate onaction_config.flags.dataCapture), andembed_route_allowlist(the platform route allowlist is now host-prop-only viaEmbedWidget(usePlatformRouteAllowlist: true)). Tenants relying on the old flags must move the opt-out todataCapture/ the host prop.
New #
AgentTriggerMode(co-pilot / workflow) — host-declared atEmbedWidget.startCall(agentTriggerMode:)and latched per call; a pureresolveCallPlandecides who owns the UI, whether panels render, and whether the avatar surface opens. The enum values areCO_PILOT/WORKFLOW(identifier-for-identifier with Android), and the mode's cross-SDK wire string is lowercasecopilot/workflow— serialize withmode.wire, read back withparseAgentTriggerMode(String?)(case- and separator-insensitive, mirrors Android's parser).- Visibility groups (
buttonVisibility) — React Native parity.EmbedWidget(buttonVisibility: EmbedButtonVisibilityConfig(groups: [...]))lets different sets of screens carry different FAB continuity / pre-show delay / delay-policy (EmbedButtonGroupConfig{id, screens, continuity, delayMs, delayPolicy}). Resolves per current route (first matching group wins); a group'sscreensalso join the allow-list. Screens in no group fall back to the widget-levelcontinuity/buttonDelay/embedButtonDelayMs. EmbedWidget.expandWidget()/embedExpandWidget()— programmatic inverse ofcollapseWidget()(emitsagent_tap_to_open);startCall()does not auto-expand.EmbedWidget.openAvatarScreen()— programmatically open the full-screen agent surface (starts a workflow call if none is running, else re-opens the surface after a collapse).action_configcoverage completed —dataCapturemaster gate,awakeningEffect/activeBorderGlow/highlighting/clickTrackingkill-switches, the three themed gradients, and all 26effects.*tuning knobs (unset knobs reproduce the built-in look exactly). New: an active-border watchdog and nudge-time FAB breathing.widget_configcompleted —position.*andagentAvatar.avatarSizemerged; sizing follows the nativeAvatarSizingrule and bar typography scales with it.isCollapsedopening state honored once per lifetime.call_idlatched from/tokenand sent flat onagent_conversation_started/_ended(Android parity).- System-back rung —
backnow sweeps every reachable navigator (deepest-first, PopScope-aware) so nested / per-tab / activity-per-screen hosts no longer exhaust the ladder.
Fixes & behavior (native parity) #
- Inactivity:
nudgeDelay <= 0= off;show_popupshows only with a non-empty tooltip;shouldAutoCollapseCard(captions suppress the fold and cancel a running countdown). - Widget UX: one centered 90/60/40 expanded-bar width; awakening plays only while no call is live and collapse returns the FAB to its dock; static collapsed avatar; avatar-open icon hidden in co-pilot; ink-square and glow-bloom collapse artifacts fixed; a silent config revalidate no longer collapses an open bar; avatar cannot surface on a co-pilot call (stale-plan race closed).
- Memory (OOM guard): the
ExplorationLognode union is now call-scoped (reset onAgentRuntime.stop, not only at mission start) and capped LRU to 12 screens, so it can no longer grow unbounded across calls for the life of a long-lived host process. - Internal:
lib/src/embed.dartsplit into focused part files; comment cleanup;CLAUDE.mdanddocs/CONFIG_WIRING.mdadded.
Fixes (device-verified) #
- Orb-flight performance. The awakening overlay no longer paints a full-screen radial-gradient bloom or two rainbow sweep-shader rings per frame: the bloom is bounded to a circle and a single burst ring is drawn, with smaller blur radii. On a mid-tier device this cut janky frames from ~10% to ~6% (raster p95 22.8 ms → 16.9 ms) — the bottleneck was fill-rate/shader churn, not blur.
- Mic and speaker toggles are single-flight. Rapid mute/unmute (or speaker)
taps no longer stack concurrent native
setMicrophoneEnabled/setSpeakerOncalls that churned the audio session and lagged the agent's speech; a burst now collapses to one native op at a time, and the stale-isMutedread is gone. - FAB collapse no longer dips. On call end the FAB settles straight at its
dock instead of dropping ~14 px and springing back — the
elasticOutlanding bounce that restarted after the FAB had already docked is removed.
Previously staged (0.0.21-dev) #
Behavioral change — retry policy. A tap/navigate whose SEMANTIC dispatch
fired but produced zero observable evidence now fails after ONE attempt
(VerificationOutcome.unknown, terminal): retrying an already-fired action
re-fires it physically (double/triple submits). Synthetic-pointer fallbacks
and null after-snapshots keep their retries — nothing semantic was delivered.
Hosts that tuned retriesPerStep for this case should rely on the backend's
failure_reason: tap_had_no_observable_effect to re-plan instead.
Source-breaking for StepVerifier subclasses. StepVerifier.verify
gained an optional named parameter UiNode? resolvedTarget (the find-ladder
winner the runner acted on). Custom verifier overrides must add it (and may
ignore it).
Also in this release: failure_reason emitted alongside error on
mission_status (the backend reads only the former); node model gains
value/checked/editable/secure with capture-time (sticky) secure
redaction — typed field contents no longer ride text or stable ids; find
ladder edge fixes (rung-1 promotion, single-token subtree hatch, IoU floor,
normalised forbid_text, container-anchored inside_text); config cache
un-brick (other_data versioned + TTL + revalidate; isLive hides only on
explicit false); wait clamp; stale-node tap refusal; CI + lib/core test
suite (180+ tests).
0.0.20 #
Fixes #
- Fixed agent audio dropping when a wired/Bluetooth headset is connected mid-call. The SDK no longer forces the audio route on a polling timer; it relies on LiveKit's native headset prioritization and reacts only to real device-change events.
- The inactivity tooltip no longer appears while a call is connecting/connected (previously it could pop up after the bar auto-collapsed).
- The inactivity tooltip now auto-dismisses on any user interaction (tap, scroll, drag), not only a FAB tap.
Features #
- The expanded voice bar auto-collapses back to the FAB after a call connects while keeping the call live. Delay is configurable via
collapsedView.collapsedTime(seconds, default 15s). - Added a "live call" pulse around the collapsed FAB that appears only after the bar fully collapses and only while the user or agent is speaking. Color is configurable via
colorPalette.pulseColor(default purple#B391F3). - The default avatar fallback now uses a Lottie animation instead of the Material
chat/personicons.
Tweaks #
- Reduced the expanded bar height, Connect-button padding, and mute/end-call button sizes.
- Bumped the SDK version reported to the backend (
sdk_version) to0.0.20.
0.0.19 #
Fixes #
- Relaxed the
livekit_clientconstraint from the exact pin2.6.5back to^2.5.3. The exact pin transitively forcedmeta ^1.17.0(required by livekit_client 2.6.5), which brokepub getfor apps on older Flutter SDKs that pinmeta 1.16.0. The range lets pub select a compatible livekit_client version per app.
0.0.18 #
FAB pre-show delay & per-flow delay policy #
- Added
embedButtonDelayMs(onEmbedWidget/EmbedProvider) — global delay before the FAB appears after navigating to an enabled route. Default0(no delay). - Added
groupDelays(Map<String, EmbedButtonDelay>) — per-flow delay override withEmbedButtonDelayPolicy:perScreen,oncePerGroupEntry,oncePerAppSession. Falls back toembedButtonDelayMs. - Added React-API aliases on
EmbedButtonContinuity:continuous(=keepVisible) andperScreen(=reset), plusEmbedButtonContinuity.fromString/EmbedButtonDelayPolicy.fromStringparsers.
Fixes #
- Nudge/inactivity countdown now starts when the FAB becomes visible (after
embedButtonDelayMs), not when the route is first entered. inactivity_behaviour: "auto_trigger"now maps toInactivityMode.AUTO_TRIGGER(auto-starts the call likestart_call); previously it silently fell back to showing the popup. AddedInactivityMode.fromBehaviour.- FAB no longer renders off-screen on the app's initial/home route — position is recomputed once the screen size is available (post first layout) and on metrics changes.
- Fixed
agentTapToOpen/agentTapToCloseenum identifiers (backend valuesagent_tap_to_open/agent_tap_to_closeunchanged).
Docs #
- Added
doc/fab-visibility-advanced.md(Flutter FAB visibility guide) anddoc/embed-button-delay.md.
0.0.17 #
- Typewriter transcription panel: vertical expansion from bottom to top when
type == "calculation"data received via LiveKit - FAB positioning:
widget_position(bottom-right,bottom-left,top-right,top-left) now respected from backend config - Fixed
bottomPaddingandrightPaddingnot applying correctly to FAB position - Bounce animation on FAB when transcription panel closes
- Analytics event names updated:
agent_tap_to_open/agent_tap_to_close SdkEventNameenum added for all internally-fired analytics event names (exported as public API)- All public event APIs (
embedEvent,embedTrackEvent, etc.) now returnFuture<bool>for send-success feedback EmbedRouteListenerwidget added for GoRouter / ShellRoute automatic route detectionEmbedNavigatorObservernow accepts optionalnameExtractorfor GoRouter alias support- Route matching now strips leading slashes — GoRouter paths (
/home) match aliases (home) - Cache-first config strategy restored in
_fetchUIConfigwith API fallback on cold start - Removed all debug logs; all exceptions handled internally — zero crash guarantee for host app
- Removed dead
_buildTranscriptionPaneloverlay (superseded by inline vertical expansion)
0.0.16 #
- Graceful exception handling across SDK — zero crash guarantee
- Fixed event routing and SDK key resolution issues
- Stability Improvements
0.0.15 #
- Stability Improvements
0.0.14 #
- Minor Bug Fixes and Stability Improvements
0.0.13 #
- Minor Bug Fixes and Stability Improvements
0.0.12 #
- Added capability to send ANALYTICS_DATA event from screens which are not part of enabled routes.
0.0.11 #
- Added ANALYTICS_DATA event for tracking structured analytics events with a specific event identifier
0.0.10 #
- Minor Bug Fixes and UI improvements
0.0.9 #
- Added rightPadding and bottomPadding to set the initial position of Embed Widget
0.0.8 #
- Added onPermissionStatusChanged callback to recieve the permission status change events
- Minor Bug Fixes and Stability Improvements
0.0.7 #
- Minor Bug Fixes and Stability Improvements
0.0.6 #
- Bluetooth Headset Support added
- Added Inactivity Actions
- Minor Bug Fixes and Stability Improvements
0.0.5 #
- Added Multi Flow Support with enabledroutes
0.0.4 #
- Added Support for Re-initialisation of embed agent
0.0.3 #
- Added Support for Buttons
- Added Route based activation
- Added embedEvent call for user generated USER_DATA nd SCREEN_STATE events
- Added Embed Config Service for management of apiKey and embedUrl
- Improved widget context extraction
- Updated Documentation
0.0.2 #
- Removed the requirement for bluetooth permissions
- Updated License
0.0.1 #
- Initial release of Embedded Agent SDK
- Core functionality for automatic widget tree traversal
- Real-time widget monitoring with collapsible interface
- Comprehensive widget property extraction
- Cross-platform support for Android and iOS
- Example applications demonstrating SDK usage
- JSON output format for widget information
- Performance-optimized widget tree analysis