send method

Future<void> send({
  1. BuildContext? context,
  2. void onChunk(
    1. String chunk
    )?,
  3. ChatStatus? endStatus = ChatStatus.idle,
})

Implementation

Future<void> send({
  BuildContext? context,
  void Function(String chunk)? onChunk,
  ChatStatus? endStatus = ChatStatus.idle,
}) async {
  try {
    if (isResponding) {
      return;
    }

    status = ChatStatus.sendingPrompt;
    notifyListeners();

    await _createConversationIfNecessary();

    var text = controller.text;
    var selfMessage = Message.user(message: text);
    conversation?.messages.add(selfMessage);
    notifyListeners();

    // Updating 'lastUpdate' date of conversation
    var updated = conversation!.recordUpdate();
    if (updated) {
      unawaited(saveThread(conversation!.id!, conversation!.metadata!));
    }

    // Preparing to fetch response
    var model = await getSavedGptModel();
    CompletionModel completion;
    if (assistant == null) {
      completion = CompletionRepository(
        dio: httpClient,
        model: model ?? GptModel.gpt4oMini,
      );
    } else {
      var rep = createAssistantRepository(assistant!.id, conversation!.id!);
      completion = rep;
    }
    var rep = ConversationRepository(
      conversation: conversation!,
      threads: createThreadsRepository(),
      completion: completion,
      onError: (exception, remainingRetries) async {
        if (context == null) {
          return;
        }
        await _showError(
          title: exception.code ?? 'Falha',
          message: exception.message,
        );
      },
      onJsonComplete: onJsonComplete,
    );

    // Streaming response
    controller.clear();
    await rep.prompt(
      previousMessages: [
        if (assistant == null) ...conversation!.messages,
      ],
      onChunk: (msg, chunk) {
        if (status != ChatStatus.answeringAndSpeaking) {
          status = ChatStatus.answering;
        }
        if (onChunk != null) onChunk(chunk);

        EasyThrottle.throttle(
          'scroll',
          Duration(milliseconds: 200),
          () {
            notifyListeners();
            _scrollToBottomIfNeeded();
          },
        );
      },
    );
    VitGptFlutterConfiguration.logger.i('Finished reading response stream');

    if (onTextResponse != null) onTextResponse!(this);
  } catch (e) {
    var msg = getErrorMessage(e) ?? 'Failed to fetch response';
    VitGptFlutterConfiguration.logger.e(msg, error: e);
    if (context != null && context.mounted) {
      await showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: const Text('Failed to get response'),
            content: Text(msg),
          );
        },
      );
    }
  } finally {
    // Updating to the end state
    if (endStatus != null) {
      status = endStatus;
    }
    notifyListeners();
  }
}