generateStream method

  1. @override
Stream<String> generateStream({
  1. required String prompt,
  2. int maxTokens = 512,
  3. String? cancelToken,
})
override

Implementation

@override
Stream<String> generateStream({
  required String prompt,
  int maxTokens = 512,
  String? cancelToken,
}) {
  final controller = StreamController<String>();
  // Subscribe first so native onListen gets called and eventSink is available
  final sub = eventsChannel.receiveBroadcastStream().listen((event) {
    if (event is Map) {
      final type = event['type'];
      if (type == 'token') {
        final text = (event['text'] as String?) ?? '';
        if (text.isNotEmpty && !controller.isClosed) controller.add(text);
      } else if (type == 'done') {
        if (kDebugMode) {
          // ignore: avoid_print
          print('[MaathaiLlamma] stream done');
        }
        if (!controller.isClosed) controller.close();
      }
    }
  }, onError: (error, stack) {
    if (kDebugMode) {
      // ignore: avoid_print
      print('[MaathaiLlamma] stream error: $error');
    }
    if (!controller.isClosed) controller.addError(error, stack);
  });

  () async {
    try {
      if (kDebugMode) {
        // ignore: avoid_print
        print('[MaathaiLlamma] startGenerateStream(maxTokens=$maxTokens)');
      }
      final started = await methodChannel.invokeMethod<bool>('startGenerateStream', {
        'prompt': prompt,
        'maxTokens': maxTokens,
        'cancelToken': cancelToken,
      });
      if (started != true) {
        throw PlatformException(code: 'start_failed', message: 'Failed to start generation stream');
      }
    } catch (e, st) {
      if (kDebugMode) {
        // ignore: avoid_print
        print('[MaathaiLlamma] startGenerateStream error: $e');
      }
      if (!controller.isClosed) controller.addError(e, st);
    }
  }();

  controller.onCancel = () async {
    if (kDebugMode) {
      // ignore: avoid_print
      print('[MaathaiLlamma] cancelGenerate');
    }
    await methodChannel.invokeMethod('cancelGenerate');
    await sub.cancel();
  };

  return controller.stream;
}