Aven App Agent Flutter SDK

aven_app_agent is the MVP alpha Flutter SDK for Aven-powered in-app assistance and guided walkthroughs.

MVP alpha status

  • Alpha package for manual Aven registration
  • Manual page registration is required
  • Manual element registration is required
  • Manual workflow registration is required
  • No automatic widget discovery
  • No automatic page discovery
  • No automatic navigation

What it does

  • Resolves end-user questions into guided workflows
  • Renders an assistant chat sheet inside your Flutter app
  • Highlights registered widgets with a walkthrough overlay
  • Continues workflows across screens when the current page changes
  • Surfaces validation, health, and debug diagnostics for manual SDK setup

What it does not do yet

  • Automatic widget discovery
  • Automatic page discovery
  • Automatic route-to-page mapping without your registration
  • Automatic workflow authoring inside the SDK

Installation

dependencies:
  aven_app_agent: ^0.2.0-alpha.1
import 'package:aven_app_agent/aven_app_agent.dart';

Backend contract

  • Official backend endpoint: POST /v1/workflows/resolve-page-context
  • The Flutter SDK sends a page-grouped contract: appContext.pages[]
  • Each registered page includes its registered elements

Quick start

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

final bookTicketButtonKey = GlobalKey();
final sourceStationKey = GlobalKey();

void setupAven() {
Aven.init(
  config: AvenConfig(
    appId: 'your-app-id',
    apiKey: 'YOUR_AVEN_API_KEY',
    baseUrl: 'https://your-api-host.example.com',
    appName: 'Your Flutter App',
    debugMode: true,
    assistantModes: const AvenAssistantModes(
      highlighter: true,
      floatingCard: true,
      speakSteps: false,
      micInput: false,
    ),
    voice: const AvenVoiceConfig(),
    theme: const AvenTheme(),
  ),
);

  Aven.registerPage(
    pageId: 'home',
    pageName: 'Home',
    route: '/',
    description: 'Landing page',
  );

  Aven.registerElement(
    pageId: 'home',
    elementId: 'book_ticket_button',
    key: bookTicketButtonKey,
    label: 'Book Ticket',
    type: 'button',
    action: 'navigate',
    targetPageId: 'book_ticket',
  );

  Aven.registerPage(
    pageId: 'book_ticket',
    pageName: 'Book Ticket',
    route: '/book-ticket',
  );

  Aven.registerElement(
    pageId: 'book_ticket',
    elementId: 'source_station_input',
    key: sourceStationKey,
    label: 'Source Station',
    type: 'text_field',
    action: 'input',
  );

  Aven.registerWorkflow(
    const AvenRegisteredWorkflow(
      workflowName: 'book_ticket',
      title: 'Book a Train Ticket',
      keywords: <String>['book', 'ticket'],
      steps: <AvenWorkflowStep>[
        AvenWorkflowStep(
          stepId: 'step_001',
          order: 1,
          pageId: 'home',
          elementId: 'book_ticket_button',
          instruction: 'Tap Book Ticket.',
          actionType: 'navigate',
        ),
        AvenWorkflowStep(
          stepId: 'step_002',
          order: 2,
          pageId: 'book_ticket',
          elementId: 'source_station_input',
          instruction: 'Enter the source station.',
          actionType: 'input',
        ),
      ],
    ),
  );

Aven.setCurrentPage('home');
}

Theming

Aven Flutter SDK now defaults to system theme resolution. The SDK reads brightness from MediaQuery.platformBrightnessOf(context) when available and falls back to WidgetsBinding.instance.platformDispatcher.platformBrightness.

Aven.init(
  config: AvenConfig(
    appId: 'your-app-id',
    apiKey: 'YOUR_AVEN_API_KEY',
    baseUrl: 'https://your-api-host.example.com',
    themeMode: AvenThemeMode.system,
  ),
);

Force light or dark mode:

AvenConfig(
  appId: 'your-app-id',
  apiKey: 'YOUR_AVEN_API_KEY',
  baseUrl: 'https://your-api-host.example.com',
  themeMode: AvenThemeMode.light,
)
AvenConfig(
  appId: 'your-app-id',
  apiKey: 'YOUR_AVEN_API_KEY',
  baseUrl: 'https://your-api-host.example.com',
  themeMode: AvenThemeMode.dark,
)

Customize the default tokens:

AvenConfig(
  appId: 'your-app-id',
  apiKey: 'YOUR_AVEN_API_KEY',
  baseUrl: 'https://your-api-host.example.com',
  themeMode: AvenThemeMode.system,
  darkTheme: const AvenThemeTokens.dark().copyWith(
    accent: Color(0xFFA78BFA),
    surface: Color(0xFF0C0C0E),
  ),
)

Notes:

  • themeMode defaults to AvenThemeMode.system
  • existing theme: AvenTheme(...) customization still works and is merged into the resolved light or dark tokens
  • the SDK themes only Aven-owned surfaces and does not force your app's MaterialApp theme

Initialization

Call Aven.init(...) once during app startup. The package validates:

  • appId
  • apiKey
  • baseUrl
  • request timeout configuration

Use a real backend URL in production. Placeholder example:

Aven.init(
  config: AvenConfig(
    appId: 'your-app-id',
    apiKey: 'YOUR_AVEN_API_KEY',
    baseUrl: 'https://your-api-host.example.com',
    assistantModes: const AvenAssistantModes(),
    voice: const AvenVoiceConfig(),
  ),
);

Flutter Voice Assistant Modes

AvenConfig now supports developer-controlled assistant modes and voice behavior:

Aven.init(
  config: AvenConfig(
    appId: 'your-app-id',
    apiKey: 'YOUR_AVEN_API_KEY',
    baseUrl: 'https://your-api-host.example.com',
    assistantModes: const AvenAssistantModes(
      highlighter: true,
      floatingCard: true,
      speakSteps: true,
      micInput: true,
    ),
    voice: const AvenVoiceConfig(
      defaultLocaleId: 'en-IN',
      supportedLocaleIds: <String>['en-IN', 'en-US', 'hi-IN'],
      speechRate: 0.88,
      pitch: 1.0,
      autoSpeakSteps: true,
      autoSubmitVoiceInput: true,
    ),
  ),
);

Developer mode presets:

assistantModes: const AvenAssistantModes(
  highlighter: true,
  floatingCard: true,
  speakSteps: false,
  micInput: false,
)
assistantModes: const AvenAssistantModes(
  highlighter: true,
  floatingCard: true,
  speakSteps: true,
  micInput: true,
)
assistantModes: const AvenAssistantModes(
  highlighter: true,
  floatingCard: true,
  speakSteps: true,
  micInput: false,
)
assistantModes: const AvenAssistantModes(
  highlighter: true,
  floatingCard: true,
  speakSteps: false,
  micInput: true,
)

Behavior notes:

  • End users only see settings toggles for modes the developer enabled during Aven.init(...).
  • Voice input uses speech_to_text and keeps the typed input field as the fallback.
  • Speak steps uses flutter_tts and device TTS quality depends on the platform speech engine.
  • The SDK does not use paid cloud STT/TTS, does not upload raw audio, and never listens continuously.

Platform permissions:

  • Android host apps must declare android.permission.RECORD_AUDIO.
  • iOS host apps must add NSMicrophoneUsageDescription and NSSpeechRecognitionUsageDescription to Info.plist.

If speech recognition or TTS is unavailable on a device, Aven keeps the typed assistant, highlighter, and walkthrough UI working normally.

Backend URL and API key configuration

  • baseUrl should point to your Aven backend host
  • apiKey should be supplied by your backend or developer configuration
  • Do not ship demo keys or localhost defaults in production builds

Manual page registration

Aven.registerPage(
  pageId: 'checkout',
  pageName: 'Checkout',
  route: '/checkout',
  description: 'Checkout screen',
);

Manual element registration

Register widgets with stable GlobalKey instances.

final payNowKey = GlobalKey();

Aven.registerElement(
  pageId: 'checkout',
  elementId: 'pay_now_button',
  key: payNowKey,
  label: 'Pay Now',
  type: 'button',
  action: 'submit',
);

Manual workflow registration

Aven.registerWorkflow(
  const AvenRegisteredWorkflow(
    workflowName: 'complete_checkout',
    title: 'Complete Checkout',
    keywords: <String>['checkout', 'pay'],
    steps: <AvenWorkflowStep>[
      AvenWorkflowStep(
        stepId: 'step_pay_now',
        order: 1,
        pageId: 'checkout',
        elementId: 'pay_now_button',
        instruction: 'Tap Pay Now to submit the order.',
      ),
    ],
  ),
);

Assistant UI setup

Wrap your app once with AvenScope so the package can render the assistant chat sheet, walkthrough overlay, and optional debug panel.

MaterialApp(
  navigatorObservers: <NavigatorObserver>[
    AvenNavigatorObserver(),
  ],
  builder: (context, child) {
    return AvenScope(
      child: child ?? const SizedBox.shrink(),
    );
  },
);

AvenScope automatically manages the built-in AvenFab.

If your app uses named routes, add AvenNavigatorObserver() so the SDK can react to route changes and continue multi-screen workflows more reliably.

Theme customization

AvenTheme is implemented and can be passed into AvenConfig.

Aven.init(
  config: AvenConfig(
    appId: 'your-app-id',
    apiKey: 'YOUR_AVEN_API_KEY',
    baseUrl: 'https://your-api-host.example.com',
    theme: const AvenTheme(
      primaryColor: Color(0xFF0A6EBD),
    ),
  ),
);

Asking questions and starting walkthroughs

End users can open the built-in assistant with:

Aven.openAssistant();

If you need to resolve a question programmatically, use the public controller:

final response = await Aven.controller.askQuestion(
  'How do I complete checkout?',
);

if (response?.workflow != null) {
  Aven.startWorkflow(response!.workflow);
}

Starting and controlling walkthroughs

Implemented controls include:

  • Aven.startWorkflow([workflow])
  • Aven.markStepCompleted(elementId)
  • Aven.clearActiveWorkflow()
  • Aven.pauseWorkflow()
  • Aven.resumeWorkflow()
  • Aven.resetSession()

Example:

Aven.startWorkflow();
Aven.markStepCompleted('pay_now_button');
Aven.pauseWorkflow();
Aven.resumeWorkflow();

Health check and diagnostics

These APIs are implemented:

  • Aven.healthCheck()
  • Aven.validateSetup()
  • Aven.getDebugState()
  • Aven.exportDebugSnapshot()
final validation = Aven.validateSetup();
final health = await Aven.healthCheck();
final debugState = Aven.getDebugState();

Missing element recovery

If a registered widget is not mounted or not on the current screen, the SDK:

  • keeps the workflow active
  • shows recovery UI instead of crashing
  • waits for the correct page
  • resumes highlighting when the target widget becomes available

Cross-screen continuation

The SDK supports workflows that continue across multiple registered screens. Keep Aven.setCurrentPage(pageId) updated whenever your app changes screens.

Aven.setCurrentPage('book_ticket');

Known limitations

  • MVP alpha package
  • Manual registration model only
  • No automatic widget discovery
  • No automatic page discovery
  • No automatic navigation
  • Widgets must be mounted before they can be highlighted

Migration

See the GuideAI Web and Flutter migration guide for the new package name, canonical import, and compatibility notes.

License

MIT

Libraries

aven_app_agent