Sample code for 30+ languages & platforms
Dart Requires Chilkat v11.2.0+

Conversation with Streaming Responses

See more AI Examples

Demonstrates an AI conversation with receiving streaming responses.

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // This example assumes the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  final ai = CkAi();

  // The provider can be "openai", "google", "claude", "deepseek", "xai", or "perplexity".
  // Support for additional providers will be added in future versions of Chilkat.
  ai.provider = 'google';

  // Use your provider's API key.
  ai.apiKey = 'MY_API_KEY';

  // Choose a model.
  ai.model = 'gemini-3.6-flash';

  // Indicate streaming mode is to be used.
  ai.streaming = true;

  // Create a new conversation to be maintained locally in memory.
  // If the conversation is the first to be created, it is also automatically selected.
  final systemMsg = 'You are a creative storyteller';
  final developerMsg = '';
  final conversationName = 'test_conversation';
  ai.newConvo(conversationName, systemMsg, developerMsg);

  // Add a text input.
  ai.inputAddText('Write a detailed story about a turtle who decides to run a bakery.  Describe the setting, the kinds of pastries, how the turtle feels, and include at least three paragraphs.');

  // Ask the AI for text output.
  try {
    ai.ask('text');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  final sbEventName = CkStringBuilder();
  final sbDelta = CkStringBuilder();
  final sbFullResponse = CkStringBuilder();
  var finished = false;
  final abortFlag = false;
  final maxWaitMs = 5000;

  while (!finished) {

    final result = ai.pollAi(abortFlag);
    if (result == 1) {
      // We have output waiting.  It should be instantly available.  The maxWaitMs is just-in-case.
      try {
        ai.nextAiEvent(maxWaitMs, sbEventName, sbDelta);
      } on ChilkatException catch (e) {
        print(e.lastErrorText);
        return;
      }

      // Some AI providers send many "empty" events.  Just ignore them.
      if (!sbEventName.contentsEqual('empty', true)) {

        // The delta contains the new output.  This could be emitted to a display or the terminal
        // as real-time output.
        if (sbEventName.contentsEqual('delta', true)) {
          // This example will emit each delta to its own line.
          print(sbDelta.getAsString());

          // Accumulate the delta's so we can show the full response later.
          sbFullResponse.appendSb(sbDelta);
        } else {
          // A streaming AI response is always terminated by a single "null_terminator" event.
          finished = sbEventName.contentsEqual('null_terminator', true);
        }
      }
    } else {
      if (result == 0) {
        // Nothing is immediately available. Sleep for 1/10 of a second before polling again.
        ai.sleepMs(100);
      } else {
        // Something failed..
        print(ai.lastErrorText);
        finished = true;
      }
    }
  }

  // -------------------------------------------------------------
  // The response is in markdown format.
  // Also see Markdown to HTML Conversion Examples.
  // -------------------------------------------------------------

  // Show the accumulated (full) response.
  print('----');
  print(sbFullResponse.getAsString());
  print('----');

  // ----------------------------------------------------------------------------------------------------------
  // For the 2nd request in this conversation, ask for a shorter version of the story.
  ai.inputAddText('Rewrite the story, but this time make it shorter, about one third as long.');
  try {
    ai.ask('text');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  sbFullResponse.clear();
  finished = false;

  while (!finished) {

    final result = ai.pollAi(abortFlag);
    if (result == 1) {
      // We have output waiting.  It should be instantly available.  The maxWaitMs is just-in-case.
      try {
        ai.nextAiEvent(maxWaitMs, sbEventName, sbDelta);
      } on ChilkatException catch (e) {
        print(e.lastErrorText);
        return;
      }

      // Some AI providers send many "empty" events.  Just ignore them.
      if (!sbEventName.contentsEqual('empty', true)) {

        // The delta contains the new output.  This could be emitted to a display or the terminal
        // as real-time output.
        if (sbEventName.contentsEqual('delta', true)) {
          // This example will emit each delta to its own line.
          print(sbDelta.getAsString());

          // Accumulate the delta's so we can show the full response later.
          sbFullResponse.appendSb(sbDelta);
        } else {
          // A streaming AI response is always terminated by a single "null_terminator" event.
          finished = sbEventName.contentsEqual('null_terminator', true);
        }
      }
    } else {
      if (result == 0) {
        // Nothing is immediately available. Sleep for 1/10 of a second before polling again.
        ai.sleepMs(100);
      } else {
        // Something failed..
        print(ai.lastErrorText);
        finished = true;
      }
    }
  }

  print('----');
  print(sbFullResponse.getAsString());
}