uncloseai.

Node.js Examples - Free LLM & TTS AI Service

Node.js Examples

This page demonstrates how to use the uncloseai. API endpoints with Node.js using the OpenAI client 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 Node.js implementation under /languages/ reads these variables and discovers each endpoint's models at startup.

Building that client in Node.js with the OpenAI library:

const OpenAI = require('openai');

// One { label, client, model } per MODEL_ENDPOINT_N, in order. N may start at 0 or 1 and have gaps.
async function endpointsFromEnv() {
    const found = [];
    for (let n = 0; n < 1000; n++) {
        const baseURL = process.env[`MODEL_ENDPOINT_${n}`];
        if (!baseURL) continue;
        const client = new OpenAI({ baseURL, apiKey: process.env[`MODEL_API_KEY_${n}`] || "none" });
        // MODEL_ID_N pins a model; unset means ask the endpoint which model it serves.
        const model = process.env[`MODEL_ID_${n}`] || (await client.models.list()).data[0].id;
        found.push({ label: process.env[`MODEL_LABEL_${n}`] || baseURL, client, model });
    }
    return found;
}

// The first endpoint is the default; the rest fail over, in order.
async function chat(messages, options = {}) {
    for (const { label, client, model } of await endpointsFromEnv()) {
        try {
            return await client.chat.completions.create({ model, messages, ...options });
        } catch (error) {
            console.error(`${label}: ${error.message}; trying the next endpoint`);
        }
    }
    throw new Error("every endpoint failed");
}

chat([{ role: "user", content: "Give a Python Fizzbuzz solution in one line of code?" }], { temperature: 0.5, max_tokens: 600 })
    .then((response) => console.log(response.choices[0].message.content));

Node.js Client Installation

To install the OpenAI package for Node.js, you can use npm in your package.json:

{
  "dependencies": {
    "openai": "6.3.0"
  }
}

Run the following command to install it:

npm install

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)

const OpenAI = require('openai');

const client = new OpenAI({
    baseURL: "https://hermes.ai.unturf.com/v1",
    apiKey: "dummy-api-key",
});

const messages = [{"role": "user", "content": "Give a Python Fizzbuzz solution in one line of code?"}];

async function getResponse() {
    try {
        // Ask the endpoint which model it serves; never hard-code an id.
        const model = (await client.models.list()).data[0].id;

        const response = await client.chat.completions.create({
            model: model,
            messages: messages,
            temperature: 0.5,
            max_tokens: 600,
        });

        console.log(response.choices[0].message.content);
    } catch (error) {
        console.error("Error:", error.response ? error.response.data : error.message);
    }
}

getResponse();

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

const OpenAI = require('openai');

const client = new OpenAI({
    baseURL: "https://qwen.ai.unturf.com/v1",
    apiKey: "dummy-api-key",
});

const messages = [{"role": "user", "content": "Give a Python Fizzbuzz solution in one line of code?"}];

async function getResponse() {
    try {
        // Ask the endpoint which model it serves; never hard-code an id.
        const model = (await client.models.list()).data[0].id;

        const response = await client.chat.completions.create({
            model: model,
            messages: messages,
            temperature: 0.5,
            max_tokens: 600,
        });

        console.log(response.choices[0].message.content);
    } catch (error) {
        console.error("Error:", error.response ? error.response.data : error.message);
    }
}

getResponse();

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)

const OpenAI = require('openai');

const client = new OpenAI({
    baseURL: "https://hermes.ai.unturf.com/v1",
    apiKey: "dummy-api-key",
});

const messages = [{"role": "user", "content": "Give a Python Fizzbuzz solution in one line of code?"}];

async function streamResponse() {
    try {
        // Ask the endpoint which model it serves; never hard-code an id.
        const model = (await client.models.list()).data[0].id;

        const stream = await client.chat.completions.create({
            model: model,
            messages: messages,
            temperature: 0.5,
            max_tokens: 600,
            stream: true,  // Enable streaming
        });

        // Use async iterator to read each chunk
        for await (const chunk of stream) {
            const msg = chunk.choices[0].delta.content;
            process.stdout.write(msg);  // Print each chunk as it arrives
        }
    } catch (error) {
        console.error("Error:", error.response ? error.response.data : error.message);
    }
}

streamResponse();

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

const OpenAI = require('openai');

const client = new OpenAI({
    baseURL: "https://qwen.ai.unturf.com/v1",
    apiKey: "dummy-api-key",
});

const messages = [{"role": "user", "content": "Give a Python Fizzbuzz solution in one line of code?"}];

async function streamResponse() {
    try {
        // Ask the endpoint which model it serves; never hard-code an id.
        const model = (await client.models.list()).data[0].id;

        const stream = await client.chat.completions.create({
            model: model,
            messages: messages,
            temperature: 0.5,
            max_tokens: 600,
            stream: true,  // Enable streaming
        });

        // Use async iterator to read each chunk
        for await (const chunk of stream) {
            const msg = chunk.choices[0].delta.content;
            process.stdout.write(msg);  // Print each chunk as it arrives
        }
    } catch (error) {
        console.error("Error:", error.response ? error.response.data : error.message);
    }
}

streamResponse();

Text-to-Speech Example

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

const OpenAI = require('openai');

const client = new OpenAI({
    baseURL: "https://speech.ai.unturf.com/v1",
    apiKey: "YOLO",
});

async function getSpeech() {
    try {
        const response = await client.audio.speech.with_streaming_response.create({
            model: "tts-1-f5",
            voice: "foxhop",
            speed: 0.9,
            input: "I think so therefore, Today is a wonderful day to grow something people love!"
        });

        response.stream_to_file("speech.mp3");
    } catch (error) {
        console.error("Error:", error.response ? error.response.data : error.message);
    }
}

getSpeech();