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();

    // Ensuring conversation is not null.
    if (conversation == null) {
      if (originalConversation != null) {
        conversation = originalConversation;
      } else {
        var created = await createThread();
        conversation = created;
        onCreate(created);
      }
    }

    // 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,
        messages: conversation!.messages,
      );
    } else {
      completion = AssistantRepository(
        dio: httpClient,
        assistantId: assistant!.id,
        threadId: conversation!.id!,
      );
    }
    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,
    );
    var text = controller.text;

    var scrollDebouncer = Debouncer(
      delay: const Duration(milliseconds: 250),
      action: () {
        _scrollToBottomIfNeeded();
        notifyListeners();
      },
    );

    // Streaming response
    controller.clear();
    await rep.prompt(
      text,
      onChunk: (msg, chunk) {
        if (status != ChatStatus.answeringAndSpeaking) {
          status = ChatStatus.answering;
        }
        if (onChunk != null) onChunk(chunk);

        scrollDebouncer.execute();
        // notifyListeners();
      },
    );
    logger.info('Finished reading response stream');

    if (onTextResponse != null) onTextResponse!(this);
  } catch (e) {
    var msg = getErrorMessage(e) ?? 'Failed to fetch response';
    logger.error(msg);
    if (context != null) {
      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();
  }
}