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:
- hermes.ai.unturf.com:
https://hermes.ai.unturf.com/v1- chat completions on an RTX 4090 - qwen.ai.unturf.com:
https://qwen.ai.unturf.com/v1- chat completions on an RTX 3090 - TTS:
https://speech.ai.unturf.com/v1- Text-to-speech generation
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:
| Variable | Meaning |
|---|---|
MODEL_ENDPOINT_N | Base 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_N | Bearer key for endpoint N. Unset means no key, which is all our free relay needs; a cloud endpoint sets one. |
MODEL_ID_N | Model id to send. Unset means ask /v1/models and take the first id, the rule used by every sample on this page. |
MODEL_LABEL_N | A display name for endpoint N; defaults to its hostname. |
TTS_ENDPOINT_N | The 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();