openChatWithConfig method

Future<void> openChatWithConfig(
  1. PupauConfig? newConfig
)

Called when chat is opened (via PupauChatUtils or tapping avatar) Resets conversation state and updates config if assistant changed Re-initializes the chat every time it's called (even with same config)

Implementation

Future<void> openChatWithConfig(PupauConfig? newConfig) async {
  PupauConfig? resolvedConfig = newConfig;
  if (resolvedConfig != null &&
      resolvedConfig.assistantId.trim().isEmpty &&
      _cachedAssistantId != null &&
      _cachedAssistantId!.trim().isNotEmpty) {
    // If the host rebuilt config from bearer token only and assistantId
    // is temporarily empty, keep the last known assistantId.
    if (resolvedConfig.bearerToken != null &&
        resolvedConfig.bearerToken!.trim().isNotEmpty) {
      resolvedConfig = PupauConfig.createWithToken(
        bearerToken: resolvedConfig.bearerToken!,
        assistantId: _cachedAssistantId!,
        apiUrl: resolvedConfig.apiUrl,
        isMarketplace: resolvedConfig.isMarketplace,
        conversationId: resolvedConfig.conversationId,
        isAnonymous: resolvedConfig.isAnonymous,
        language: resolvedConfig.language,
        googleMapsApiKey: resolvedConfig.googleMapsApiKey,
        hideInputBox: resolvedConfig.hideInputBox,
        widgetMode: resolvedConfig.widgetMode,
        sizedConfig: resolvedConfig.sizedConfig,
        floatingConfig: resolvedConfig.floatingConfig,
        showNerdStats: resolvedConfig.showNerdStats,
        hideAudioRecordingButton: resolvedConfig.hideAudioRecordingButton,
        customProperties: resolvedConfig.customProperties,
        conversationStarters: resolvedConfig.conversationStarters,
        appBarConfig: resolvedConfig.appBarConfig,
        drawerConfig: resolvedConfig.drawerConfig,
        resetChatOnOpen: resolvedConfig.resetChatOnOpen,
        initialWelcomeMessage: resolvedConfig.initialWelcomeMessage,
      );
    }
  }

  // Wait for any ongoing initialization to complete before starting a new one
  // This ensures proper config updates when switching agents
  if (_isInitializing && _initializationCompleter != null) {
    await _initializationCompleter!.future;
  }

  // Check if assistant or anonymous mode changed
  bool assistantChanged =
      pupauConfig?.assistantId != resolvedConfig?.assistantId ||
      pupauConfig?.isMarketplace != resolvedConfig?.isMarketplace;
  bool anonymousChanged =
      pupauConfig?.isAnonymous != resolvedConfig?.isAnonymous;
  if (resolvedConfig != null) {
    pupauConfig = resolvedConfig;
    ApiUrls.setApiUrlOverride(resolvedConfig.apiUrl);
    hideInputBox.value = resolvedConfig.hideInputBox;
  }
  // Show new agent in UI immediately from cache if available (no network delay)
  applyCachedAssistantIfAvailable();
  // Reset chat state if assistant changed OR anonymous mode changed
  // This ensures proper reset when toggling anonymous mode
  if (assistantChanged || anonymousChanged) {
    resetChatState();
  }
  _updateBootStatus(BootState.pending);

  // Initialize chat with current config (always re-initialize when chat is opened)
  _isInitializing = true;
  final completer = Completer<void>();
  _initializationCompleter = completer;
  try {
    await initChatController();
    if (!completer.isCompleted) {
      completer.complete();
    }
  } catch (e) {
    if (!completer.isCompleted) {
      completer.completeError(e);
    }
    rethrow;
  } finally {
    _isInitializing = false;
    // Only clear if this is still the current completer (in case a new init started)
    if (_initializationCompleter == completer) {
      _initializationCompleter = null;
    }
  }
}