uncloseai.

Dart Examples - Free LLM & TTS AI Service

Dart Examples

This page demonstrates how to use the uncloseai. API endpoints with Dart/Flutter using the dart_openai community library. All examples use the same OpenAI-compatible API interface, making it easy to switch between different models and endpoints.

Available Endpoints:

Both chat hostnames currently serve the same model, turboderp/Qwen3.8-27B-exl3 (read live from /v1/models). Hostnames are routing labels, not model names: every example below asks the endpoint which model it serves instead of hard-coding an id, so a model swap on the cards never breaks your code. The served model reasons before it answers (the reasoning arrives in a separate reasoning field), so give it room: the samples ask for 600 tokens because at 150 the budget ran out before the answer began.

Many endpoints from environment variables

Our clients (uncloseai-cli, uncloseai.js, opencompletion and the downloadable implementation for every language on this site) share one convention, so an endpoint is configuration, never code:

VariableMeaning
MODEL_ENDPOINT_NBase URL of the N-th OpenAI-compatible endpoint, ending in /v1. The only required variable. Scan N from 0 upward and skip gaps: uncloseai-cli counts from 0, the per-language implementations from 1.
MODEL_API_KEY_NBearer key for endpoint N. Unset means no key, which is all our free relay needs; a cloud endpoint sets one.
MODEL_ID_NModel id to send. Unset means ask /v1/models and take the first id, the rule used by every sample on this page.
MODEL_LABEL_NA display name for endpoint N; defaults to its hostname.
TTS_ENDPOINT_NThe same shape for text-to-speech endpoints.
export MODEL_ENDPOINT_0="https://hermes.ai.unturf.com/v1"
export MODEL_ENDPOINT_1="https://qwen.ai.unturf.com/v1"
# export MODEL_API_KEY_1="sk-..."      # only for an endpoint that needs one
export TTS_ENDPOINT_0="https://speech.ai.unturf.com/v1"

The first endpoint is the default; the rest fail over, in order. The Dart implementation under /languages/ reads these variables and discovers each endpoint's models at startup.

Dart Client Installation

Add dart_openai to your pubspec.yaml:

dependencies:
  dart_openai: ^5.1.0

Non-Streaming Examples

Non-streaming mode waits for the complete response before returning. This is simpler to use but provides no intermediate feedback during generation.

Using hermes.ai.unturf.com (RTX 4090)

import 'package:dart_openai/dart_openai.dart';

void main() async {
  OpenAI.apiKey = "choose-any-value";
  // dart_openai appends /v1 to every path itself; hand it the host only.
  OpenAI.baseUrl = "https://hermes.ai.unturf.com";

  // Ask the endpoint which model it serves; never hard-code an id.
  final model = (await OpenAI.instance.model.list()).first.id;

  final chatCompletion = await OpenAI.instance.chat.create(
    model: model,
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        role: OpenAIChatMessageRole.user,
        content: [
          OpenAIChatCompletionChoiceMessageContentItemModel.text(
            "Give a Python Fizzbuzz solution in one line of code?"
          ),
        ],
      ),
    ],
    temperature: 0.5,
    maxTokens: 600,
  );

  print(chatCompletion.choices.first.message.content?.first.text);
}

Using qwen.ai.unturf.com (RTX 3090)

import 'package:dart_openai/dart_openai.dart';

void main() async {
  OpenAI.apiKey = "choose-any-value";
  // dart_openai appends /v1 to every path itself; hand it the host only.
  OpenAI.baseUrl = "https://qwen.ai.unturf.com";

  // Ask the endpoint which model it serves; never hard-code an id.
  final model = (await OpenAI.instance.model.list()).first.id;

  final chatCompletion = await OpenAI.instance.chat.create(
    model: model,
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        role: OpenAIChatMessageRole.user,
        content: [
          OpenAIChatCompletionChoiceMessageContentItemModel.text(
            "Give a Python Fizzbuzz solution in one line of code?"
          ),
        ],
      ),
    ],
    temperature: 0.5,
    maxTokens: 600,
  );

  print(chatCompletion.choices.first.message.content?.first.text);
}

Streaming Examples

Streaming mode returns chunks of the response as they are generated, providing real-time feedback. This is ideal for interactive applications and long responses.

Using hermes.ai.unturf.com (RTX 4090)

import 'package:dart_openai/dart_openai.dart';
import 'dart:io';

void main() async {
  OpenAI.apiKey = "choose-any-value";
  // dart_openai appends /v1 to every path itself; hand it the host only.
  OpenAI.baseUrl = "https://hermes.ai.unturf.com";

  // Ask the endpoint which model it serves; never hard-code an id.
  final model = (await OpenAI.instance.model.list()).first.id;

  final chatStream = OpenAI.instance.chat.createStream(
    model: model,
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        role: OpenAIChatMessageRole.user,
        content: [
          OpenAIChatCompletionChoiceMessageContentItemModel.text(
            "Give a Python Fizzbuzz solution in one line of code?"
          ),
        ],
      ),
    ],
    temperature: 0.5,
    maxTokens: 600,
  );

  await for (final chunk in chatStream) {
    final content = chunk.choices.first.delta.content;
    if (content != null && content.isNotEmpty) {
      stdout.write(content.first.text);
    }
  }
}

Using qwen.ai.unturf.com (RTX 3090)

import 'package:dart_openai/dart_openai.dart';
import 'dart:io';

void main() async {
  OpenAI.apiKey = "choose-any-value";
  // dart_openai appends /v1 to every path itself; hand it the host only.
  OpenAI.baseUrl = "https://qwen.ai.unturf.com";

  // Ask the endpoint which model it serves; never hard-code an id.
  final model = (await OpenAI.instance.model.list()).first.id;

  final chatStream = OpenAI.instance.chat.createStream(
    model: model,
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        role: OpenAIChatMessageRole.user,
        content: [
          OpenAIChatCompletionChoiceMessageContentItemModel.text(
            "Give a Python Fizzbuzz solution in one line of code?"
          ),
        ],
      ),
    ],
    temperature: 0.5,
    maxTokens: 600,
  );

  await for (final chunk in chatStream) {
    final content = chunk.choices.first.delta.content;
    if (content != null && content.isNotEmpty) {
      stdout.write(content.first.text);
    }
  }
}

Text-to-Speech Example

Generate audio speech from text using the TTS endpoint. The audio is saved as an MP3 file.

import 'package:dart_openai/dart_openai.dart';
import 'dart:io';

void main() async {
  OpenAI.apiKey = "YOLO";
  // dart_openai appends /v1 to every path itself; hand it the host only.
  OpenAI.baseUrl = "https://speech.ai.unturf.com";

  // createSpeech writes the audio itself and returns the File. With no
  // outputDirectory it writes to "/", so point it at the current directory.
  final File file = await OpenAI.instance.audio.createSpeech(
    model: "tts-1-f5",
    input: "I think so therefore, Today is a wonderful day to grow something people love!",
    voice: "foxhop",
    speed: 0.9,
    responseFormat: OpenAIAudioSpeechResponseFormat.mp3,
    outputFileName: "speech",
    outputDirectory: Directory.current,
  );

  print("Audio saved to: ${file.path}");
}