add official OpenAI SDK client examples for Go, Ruby, Java, and C#

This commit is contained in:
Russell Ballestrini 2025-10-15 15:25:32 -04:00
parent bfc41a22a0
commit 0cf61ea676
12 changed files with 519 additions and 0 deletions

View file

@ -0,0 +1,22 @@
# Use official .NET SDK to build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
WORKDIR /app
# Copy project file and restore dependencies
COPY uncloseai.csproj ./
RUN dotnet restore
# Copy source and build
COPY uncloseai.cs ./
RUN dotnet build -c Release -o /app/build
# Run stage
FROM mcr.microsoft.com/dotnet/runtime:8.0
WORKDIR /app
# Copy built application from builder
COPY --from=builder /app/build .
CMD ["dotnet", "uncloseai.dll"]

View file

@ -0,0 +1,96 @@
using System;
using System.IO;
using System.Threading.Tasks;
using OpenAI;
using OpenAI.Chat;
using OpenAI.Audio;
class uncloseai
{
static async Task Main(string[] args)
{
Console.WriteLine("=== UncloseAI C# Client (Official OpenAI SDK) ===\n");
// Non-streaming chat with Hermes
Console.WriteLine("=== Non-Streaming Chat (Hermes) ===");
var hermesClient = new ChatClient(
model: "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic",
apiKey: "dummy-key",
new OpenAIClientOptions
{
Endpoint = new Uri("https://hermes.ai.unturf.com/v1")
}
);
var hermesResponse = await hermesClient.CompleteChatAsync(
new[]
{
new UserChatMessage("Give a Python Fizzbuzz solution in one line of code?")
},
new ChatCompletionOptions
{
Temperature = 0.5f,
MaxOutputTokenCount = 150
}
);
Console.WriteLine($"Response: {hermesResponse.Value.Content[0].Text}\n");
// Streaming chat with Qwen
Console.WriteLine("=== Streaming Chat (Qwen) ===");
var qwenClient = new ChatClient(
model: "hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M",
apiKey: "dummy-key",
new OpenAIClientOptions
{
Endpoint = new Uri("https://qwen.ai.unturf.com/v1")
}
);
Console.Write("Response: ");
await foreach (var update in qwenClient.CompleteChatStreamingAsync(
new[]
{
new UserChatMessage("Give a Python Fizzbuzz solution in one line of code?")
},
new ChatCompletionOptions
{
Temperature = 0.5f,
MaxOutputTokenCount = 150
}
))
{
foreach (var contentPart in update.ContentUpdate)
{
Console.Write(contentPart.Text);
}
}
Console.WriteLine("\n");
// TTS example
Console.WriteLine("=== TTS Speech Generation ===");
var ttsClient = new AudioClient(
model: "tts-1",
apiKey: "YOLO",
new OpenAIClientOptions
{
Endpoint = new Uri("https://speech.ai.unturf.com/v1")
}
);
var speech = await ttsClient.GenerateSpeechAsync(
"I think so therefore, Today is a wonderful day to grow something people love!",
GeneratedSpeechVoice.Alloy,
new SpeechGenerationOptions
{
Speed = 0.9f
}
);
await File.WriteAllBytesAsync("speech.mp3", speech.Value.ToArray());
var fileInfo = new FileInfo("speech.mp3");
Console.WriteLine($"[OK] Speech file created: speech.mp3 ({fileInfo.Length} bytes)\n");
Console.WriteLine("=== Examples Complete ===");
}
}

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenAI" Version="2.5.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,26 @@
# Multi-stage build for Go with official OpenAI SDK
FROM golang:1.22-alpine AS builder
WORKDIR /app
# Copy go mod files
COPY go.mod ./
RUN go mod download
# Copy source code
COPY main.go ./
# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -o /uncloseai main.go
# Final stage
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /uncloseai ./
# Set environment variables for testing
ENV MODEL_ENDPOINT_1=https://hermes.ai.unturf.com
ENV MODEL_ENDPOINT_2=https://qwen.ai.unturf.com
ENV TTS_ENDPOINT_1=https://speech.ai.unturf.com
CMD ["./uncloseai"]

View file

@ -0,0 +1,5 @@
module uncloseai-go-openai
go 1.22
require github.com/openai/openai-go v0.1.0-alpha.39

102
languages/go/openai/main.go Normal file
View file

@ -0,0 +1,102 @@
package main
import (
"context"
"fmt"
"io"
"os"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
func main() {
fmt.Println("=== UncloseAI Go Client (Official OpenAI SDK) ===\n")
// Non-streaming chat with Hermes
fmt.Println("=== Non-Streaming Chat (Hermes) ===")
hermesClient := openai.NewClient(
option.WithBaseURL("https://hermes.ai.unturf.com/v1"),
option.WithAPIKey("dummy-key"),
)
chatResponse, err := hermesClient.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: openai.F("adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic"),
Messages: openai.F([]openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Give a Python Fizzbuzz solution in one line of code?"),
}),
Temperature: openai.Float(0.5),
MaxTokens: openai.Int(150),
})
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf("Response: %s\n\n", chatResponse.Choices[0].Message.Content)
}
// Streaming chat with Qwen
fmt.Println("=== Streaming Chat (Qwen) ===")
qwenClient := openai.NewClient(
option.WithBaseURL("https://qwen.ai.unturf.com/v1"),
option.WithAPIKey("dummy-key"),
)
stream := qwenClient.Chat.Completions.NewStreaming(context.Background(), openai.ChatCompletionNewParams{
Model: openai.F("hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M"),
Messages: openai.F([]openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Give a Python Fizzbuzz solution in one line of code?"),
}),
Temperature: openai.Float(0.5),
MaxTokens: openai.Int(150),
})
fmt.Print("Response: ")
for stream.Next() {
chunk := stream.Current()
if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
fmt.Print(chunk.Choices[0].Delta.Content)
}
}
if err := stream.Err(); err != nil {
fmt.Printf("\nStream error: %v\n", err)
}
fmt.Println("\n")
// TTS example
fmt.Println("=== TTS Speech Generation ===")
ttsClient := openai.NewClient(
option.WithBaseURL("https://speech.ai.unturf.com/v1"),
option.WithAPIKey("YOLO"),
)
response, err := ttsClient.Audio.Speech.New(context.Background(), openai.AudioSpeechNewParams{
Model: openai.F(openai.SpeechModelTTS1),
Voice: openai.F(openai.AudioSpeechNewParamsVoiceAlloy),
Input: openai.F("I think so therefore, Today is a wonderful day to grow something people love!"),
Speed: openai.Float(0.9),
})
if err != nil {
fmt.Printf("TTS Error: %v\n", err)
} else {
defer response.Body.Close()
out, err := os.Create("speech.mp3")
if err != nil {
fmt.Printf("File creation error: %v\n", err)
} else {
defer out.Close()
_, err = io.Copy(out, response.Body)
if err != nil {
fmt.Printf("File write error: %v\n", err)
} else {
fileInfo, _ := os.Stat("speech.mp3")
fmt.Printf("[OK] Speech file created: speech.mp3 (%d bytes)\n", fileInfo.Size())
}
}
}
fmt.Println("\n=== Examples Complete ===")
}

View file

@ -0,0 +1,26 @@
# Use official Maven image to build
FROM maven:3.9-eclipse-temurin-17-alpine AS builder
WORKDIR /app
# Copy POM and source
COPY pom.xml ./
COPY uncloseai.java ./
# Build the application
RUN mvn clean compile
# Run stage
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Copy compiled classes and dependencies from builder
COPY --from=builder /app/target/classes ./classes
COPY --from=builder /root/.m2/repository /root/.m2/repository
COPY --from=builder /app/pom.xml ./
# Install maven to have classpath available
RUN apk add --no-cache maven
CMD ["mvn", "-q", "exec:java"]

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.uncloseai</groupId>
<artifactId>uncloseai-java-openai</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.8.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<mainClass>uncloseai</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,94 @@
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.*;
import com.openai.core.JsonValue;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.stream.Stream;
public class uncloseai {
public static void main(String[] args) {
System.out.println("=== UncloseAI Java Client (Official OpenAI SDK) ===\n");
// Non-streaming chat with Hermes
System.out.println("=== Non-Streaming Chat (Hermes) ===");
OpenAIClient hermesClient = OpenAIOkHttpClient.builder()
.apiKey("dummy-key")
.baseURL("https://hermes.ai.unturf.com/v1")
.build();
ChatCompletionCreateParams hermesParams = ChatCompletionCreateParams.builder()
.model("adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic")
.addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
ChatCompletionUserMessageParam.builder()
.role(ChatCompletionUserMessageParam.Role.USER)
.content(ChatCompletionUserMessageParam.Content.ofTextContent(
"Give a Python Fizzbuzz solution in one line of code?"
))
.build()
))
.temperature(0.5)
.maxTokens(150L)
.build();
ChatCompletion hermesResponse = hermesClient.chat().completions().create(hermesParams);
System.out.println("Response: " + hermesResponse.choices().get(0).message().content().get() + "\n");
// Streaming chat with Qwen
System.out.println("=== Streaming Chat (Qwen) ===");
OpenAIClient qwenClient = OpenAIOkHttpClient.builder()
.apiKey("dummy-key")
.baseURL("https://qwen.ai.unturf.com/v1")
.build();
ChatCompletionCreateParams qwenParams = ChatCompletionCreateParams.builder()
.model("hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M")
.addMessage(ChatCompletionMessageParam.ofChatCompletionUserMessageParam(
ChatCompletionUserMessageParam.builder()
.role(ChatCompletionUserMessageParam.Role.USER)
.content(ChatCompletionUserMessageParam.Content.ofTextContent(
"Give a Python Fizzbuzz solution in one line of code?"
))
.build()
))
.temperature(0.5)
.maxTokens(150L)
.build();
System.out.print("Response: ");
Stream<ChatCompletionChunk> qwenStream = qwenClient.chat().completions().createStreaming(qwenParams);
qwenStream.forEach(chunk -> {
if (!chunk.choices().isEmpty() && chunk.choices().get(0).delta().content().isPresent()) {
System.out.print(chunk.choices().get(0).delta().content().get());
}
});
System.out.println("\n");
// TTS example
System.out.println("=== TTS Speech Generation ===");
OpenAIClient ttsClient = OpenAIOkHttpClient.builder()
.apiKey("YOLO")
.baseURL("https://speech.ai.unturf.com/v1")
.build();
SpeechCreateParams speechParams = SpeechCreateParams.builder()
.model(SpeechModel.TTS_1)
.voice(SpeechCreateParams.Voice.ALLOY)
.input("I think so therefore, Today is a wonderful day to grow something people love!")
.speed(0.9)
.build();
byte[] audioBytes = ttsClient.audio().speech().create(speechParams);
try (FileOutputStream fos = new FileOutputStream("speech.mp3")) {
fos.write(audioBytes);
System.out.println("[OK] Speech file created: speech.mp3 (" + audioBytes.length + " bytes)\n");
} catch (IOException e) {
System.err.println("Error writing audio file: " + e.getMessage());
}
System.out.println("=== Examples Complete ===");
}
}

View file

@ -0,0 +1,16 @@
# Use official Ruby image
FROM ruby:3.3-slim
WORKDIR /app
# Copy Gemfile
COPY Gemfile ./
# Install dependencies
RUN bundle install
# Copy source code
COPY uncloseai.rb ./
RUN chmod +x uncloseai.rb
CMD ["ruby", "uncloseai.rb"]

View file

@ -0,0 +1,3 @@
source 'https://rubygems.org'
gem 'openai', '~> 0.30.0'

View file

@ -0,0 +1,73 @@
#!/usr/bin/env ruby
# UncloseAI - Ruby Client using Official OpenAI SDK
# A Ruby client for OpenAI-compatible APIs with streaming support
require 'openai'
puts "=== UncloseAI Ruby Client (Official OpenAI SDK) ===\n\n"
# Non-streaming chat with Hermes
puts "=== Non-Streaming Chat (Hermes) ==="
hermes_client = OpenAI::Client.new(
access_token: "dummy-key",
uri_base: "https://hermes.ai.unturf.com/v1"
)
response = hermes_client.chat(
parameters: {
model: "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic",
messages: [
{ role: "user", content: "Give a Python Fizzbuzz solution in one line of code?" }
],
temperature: 0.5,
max_tokens: 150
}
)
puts "Response: #{response.dig('choices', 0, 'message', 'content')}\n\n"
# Streaming chat with Qwen
puts "=== Streaming Chat (Qwen) ==="
qwen_client = OpenAI::Client.new(
access_token: "dummy-key",
uri_base: "https://qwen.ai.unturf.com/v1"
)
print "Response: "
qwen_client.chat(
parameters: {
model: "hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M",
messages: [
{ role: "user", content: "Give a Python Fizzbuzz solution in one line of code?" }
],
temperature: 0.5,
max_tokens: 150,
stream: proc do |chunk, _bytesize|
content = chunk.dig('choices', 0, 'delta', 'content')
print content if content
end
}
)
puts "\n\n"
# TTS example
puts "=== TTS Speech Generation ==="
tts_client = OpenAI::Client.new(
access_token: "YOLO",
uri_base: "https://speech.ai.unturf.com/v1"
)
response = tts_client.audio.speech(
parameters: {
model: "tts-1",
voice: "alloy",
input: "I think so therefore, Today is a wonderful day to grow something people love!",
speed: 0.9
}
)
File.binwrite("speech.mp3", response)
file_size = File.size("speech.mp3")
puts "[OK] Speech file created: speech.mp3 (#{file_size} bytes)\n\n"
puts "=== Examples Complete ==="