initializeServices static method

Future<SdkInitResult?> initializeServices({
  1. String? apiKey,
  2. String? baseURL,
  3. String? deviceId,
  4. String? buildToken,
  5. bool forceRefreshAssignments = false,
  6. bool flushTelemetry = true,
  7. bool discoverDownloadedModels = true,
  8. bool rescanLocalModels = true,
})

Initialize service bridges.

This is Phase 2 of 2-phase initialization:

  1. Setup HTTP transport/native config (if needed)
  2. Register platform-owned async callbacks and secure-storage caches
  3. Initialize C++ state/auth secure storage with resolved credentials
  4. Drive commons-owned deterministic Phase 2 orchestration

Call this AFTER Phase 1. Can be called in background.

apiKey API key for production/staging baseURL Backend URL for production/staging deviceId Device identifier

Implementation

static Future<SdkInitResult?> initializeServices({
  String? apiKey,
  String? baseURL,
  String? deviceId,
  String? buildToken,
  bool forceRefreshAssignments = false,
  bool flushTelemetry = true,
  bool discoverDownloadedModels = true,
  bool rescanLocalModels = true,
}) async {
  if (!_isInitialized) {
    throw StateError('Must call initialize() before initializeServices()');
  }

  if (_servicesInitialized) {
    _logger.debug('Services already initialized, skipping');
    return null;
  }

  _logger.debug('Starting Phase 2 services initialization');

  // Step 1: HTTP transport — configure C++ HTTP layer BEFORE phase2 so that
  // rac_sdk_init_phase2_proto's device-registration POST has a live transport.
  // Mirrors Swift Step 1 in _performServicesInitialization(): setupHTTP runs
  // before CppBridge.SdkInit.phase2() (RunAnywhere.swift:266-279 → :287).
  if (!DartBridgeHTTP.instance.isConfigured) {
    try {
      await DartBridgeHTTP.instance.configure(
        environment: _environment,
        apiKey: apiKey,
        baseURL: baseURL,
      );
      _logger.debug('HTTP transport configured');
    } catch (_) {
      _logger.warning('HTTP setup failed; SDK remains offline');
    }
  }

  // Step 2: Register platform-owned async callbacks before commons Phase 2.
  // Device registration itself is owned by rac_sdk_init_phase2_proto; this
  // call only installs callbacks, SharedPreferences, and the cached device id.
  await DartBridgeDevice.register(
    environment: _environment,
    baseURL: baseURL,
  );
  _logger.debug('Device callbacks wired for Phase 2');

  // Platform services registration also drains the async secure-storage cache
  // used by commons device/model discovery callbacks.
  await DartBridgePlatform.registerServices();
  _logger.debug('Platform services registered');

  // Step 3: Install auth secure storage now that platform async caches are
  // ready. Commons Phase 1 already owns rac_state_initialize with the
  // resolved credentials/device ID.
  await DartBridgeState.instance.initialize(
    environment: _environment,
    baseURL: baseURL,
  );
  _logger.debug('Auth secure storage initialized');

  // Step 4: Drive the canonical Phase 2 step-list inside commons. HTTP and
  // platform callbacks are configured, and model paths are set by
  // RunAnywhere._runPhase2 before this call so commons can discover local
  // downloads through the global registry.
  // Soft failures (offline mode, missing creds) come back as
  // success=true + warning; hard failures throw.
  SdkInitResult? phase2Result;
  try {
    final result = DartBridgeSdkInit.phase2(
      SdkInitPhase2Request(
        buildToken: buildToken ?? DartBridgeDevConfig.buildToken ?? '',
        forceRefreshAssignments: forceRefreshAssignments,
        flushTelemetry: flushTelemetry,
        discoverDownloadedModels: discoverDownloadedModels,
        rescanLocalModels: rescanLocalModels,
      ),
    );
    phase2Result = result;
    _logger.debug(
      'SDK Phase 2 (proto) complete',
      metadata: {
        'httpConfigured': result.httpConfigured,
        'deviceRegistered': result.deviceRegistered,
        'linkedModelsCount': result.linkedModelsCount,
        'discoveredOrphans': result.discoveredOrphans,
        'hasCompletedHttpSetup': result.hasCompletedHttpSetup,
        'durationMs': result.durationMs.toInt(),
        'hasWarning': result.hasWarning(),
      },
    );
  } catch (_) {
    // Non-fatal: services init may still succeed via the per-bridge
    // registrations below even when the C++ step-list reports an error.
    _logger.warning('SDK Phase 2 proto failed');
  }

  // Flutter-only async bridge: commons Phase 2 owns device registration,
  // but the Dart FFI device http_post callback can only capture the request.
  // Drain the captured POST after the C ABI returns.
  await DartBridgeDevice.flushPendingRegistrationPost();

  _servicesInitialized = true;
  _logger.info('Phase 2 services initialization complete');
  return phase2Result;
}