modified: CLAUDE.md modified: Makefile new file: languages/awk/Dockerfile new file: languages/awk/uncloseai.awk modified: languages/bash/Dockerfile deleted: languages/bash/examples.sh new file: languages/bash/uncloseai.sh new file: languages/c/curl/Dockerfile new file: languages/c/curl/Makefile new file: languages/c/curl/index.html new file: languages/c/curl/uncloseai.c new file: languages/c/libh2o/Dockerfile new file: languages/c/libh2o/Makefile new file: languages/c/libh2o/uncloseai.c new file: languages/c/nghttp2/Dockerfile new file: languages/c/nghttp2/Makefile new file: languages/c/nghttp2/uncloseai.c new file: languages/clojure/Dockerfile new file: languages/clojure/deps.edn new file: languages/clojure/uncloseai.clj new file: languages/cobol/Dockerfile new file: languages/cobol/discover.sh new file: languages/cobol/hermes.sh new file: languages/cobol/qwen.sh new file: languages/cobol/tts.sh new file: languages/cobol/uncloseai.cob new file: languages/cpp/boost-beast/Dockerfile new file: languages/cpp/boost-beast/Makefile new file: languages/cpp/boost-beast/uncloseai.cpp new file: languages/cpp/cpp-httplib/Dockerfile new file: languages/cpp/cpp-httplib/Makefile new file: languages/cpp/cpp-httplib/uncloseai.cpp new file: languages/cpp/libcurl/Dockerfile new file: languages/cpp/libcurl/Makefile new file: languages/cpp/libcurl/uncloseai.cpp new file: languages/crystal/Dockerfile new file: languages/crystal/uncloseai.cr new file: languages/csharp/Dockerfile new file: languages/csharp/Uncloseai.cs new file: languages/csharp/csharp.csproj new file: languages/dart/Dockerfile new file: languages/dart/bin/uncloseai.dart new file: languages/dart/pubspec.yaml new file: languages/deno/Dockerfile new file: languages/deno/uncloseai.ts new file: languages/elixir/Dockerfile new file: languages/elixir/lib/uncloseai.ex new file: languages/elixir/mix.exs new file: languages/elixir/run.exs new file: languages/erlang/Dockerfile new file: languages/erlang/rebar.config new file: languages/erlang/src/uncloseai.app.src new file: languages/erlang/src/uncloseai.erl new file: languages/fortran/Dockerfile new file: languages/fortran/uncloseai.f90 new file: languages/fsharp/Dockerfile new file: languages/fsharp/Uncloseai.fs new file: languages/fsharp/fsharp.fsproj new file: languages/go/Dockerfile new file: languages/go/README.md new file: languages/go/examples/basic.go new file: languages/go/go.mod new file: languages/go/uncloseai.go new file: languages/go/uncloseai/uncloseai.go new file: languages/haskell/Dockerfile new file: languages/haskell/UncloseAI.hs new file: languages/haskell/uncloseai.cabal new file: languages/java/Dockerfile new file: languages/java/UncloseAI.java new file: languages/javascript/bun/Dockerfile new file: languages/javascript/bun/uncloseai.ts new file: languages/javascript/nodejs/Dockerfile new file: languages/javascript/nodejs/README.md new file: languages/javascript/nodejs/package.json new file: languages/javascript/nodejs/uncloseai.js new file: languages/javascript/typescript/Dockerfile new file: languages/javascript/typescript/package.json new file: languages/javascript/typescript/tsconfig.json new file: languages/javascript/typescript/uncloseai.ts new file: languages/javascript/vanilla/Dockerfile new file: languages/javascript/vanilla/uncloseai.html new file: languages/julia/Dockerfile new file: languages/julia/Project.toml new file: languages/julia/src/uncloseai.jl new file: languages/kotlin/Dockerfile new file: languages/kotlin/build.gradle.kts new file: languages/kotlin/src/main/kotlin/UncloseAI.kt new file: languages/kotlin/uncloseai.kt new file: languages/lua/Dockerfile new file: languages/lua/uncloseai.lua new file: languages/nim/Dockerfile new file: languages/nim/uncloseai.nim new file: languages/ocaml/Dockerfile new file: languages/ocaml/dune new file: languages/ocaml/dune-project new file: languages/ocaml/uncloseai.ml new file: languages/odin/Dockerfile new file: languages/odin/uncloseai.odin new file: languages/perl/Dockerfile new file: languages/perl/uncloseai.pl new file: languages/php/Dockerfile new file: languages/php/uncloseai.php new file: languages/powershell/Dockerfile new file: languages/powershell/uncloseai.ps1 new file: languages/prolog/Dockerfile new file: languages/prolog/uncloseai.pl new file: languages/python/aiohttp/Dockerfile new file: languages/python/aiohttp/requirements.txt new file: languages/python/aiohttp/uncloseai.py modified: languages/python/httpx-async/Dockerfile deleted: languages/python/httpx-async/examples.py new file: languages/python/httpx-async/uncloseai.py modified: languages/python/openai-client/Dockerfile deleted: languages/python/openai-client/examples.py new file: languages/python/openai-client/uncloseai.py modified: languages/python/requests/Dockerfile deleted: languages/python/requests/examples.py new file: languages/python/requests/uncloseai.py new file: languages/r/Dockerfile new file: languages/r/uncloseai.R new file: languages/ruby/Dockerfile new file: languages/ruby/README.md new file: languages/ruby/uncloseai.rb new file: languages/rust/Cargo.toml new file: languages/rust/Dockerfile new file: languages/rust/README.md new file: languages/rust/examples/basic.rs new file: languages/rust/src/lib.rs new file: languages/rust/src/uncloseai.rs new file: languages/scala/Dockerfile new file: languages/scala/build.sbt new file: languages/scala/project/build.properties new file: languages/scala/project/plugins.sbt new file: languages/scala/src/main/scala/UncloseAI.scala new file: languages/tcl/Dockerfile new file: languages/tcl/uncloseai.tcl new file: languages/v/Dockerfile new file: languages/v/uncloseai.v new file: languages/v/v.mod new file: languages/vbnet/Dockerfile new file: languages/vbnet/UncloseAI.vb new file: languages/vbnet/UncloseAI.vbproj modified: languages/zig/Dockerfile modified: languages/zig/build.zig deleted: languages/zig/src/main.zig new file: languages/zig/src/uncloseai.zig
306 lines
9.6 KiB
C#
306 lines
9.6 KiB
C#
using System;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
|
|
class ModelInfo
|
|
{
|
|
public string Id { get; set; } = "";
|
|
public string Endpoint { get; set; } = "";
|
|
public int MaxTokens { get; set; } = 8192;
|
|
}
|
|
|
|
class Uncloseai
|
|
{
|
|
static readonly HttpClient client = new HttpClient();
|
|
static readonly List<ModelInfo> models = new List<ModelInfo>();
|
|
static readonly List<string> ttsEndpoints = new List<string>();
|
|
|
|
static async Task DiscoverModelsFromEndpoint(string endpoint)
|
|
{
|
|
Console.WriteLine($"Discovering models from: {endpoint}");
|
|
try
|
|
{
|
|
var response = await client.GetAsync($"{endpoint}/models");
|
|
var body = await response.Content.ReadAsStringAsync();
|
|
|
|
using var doc = JsonDocument.Parse(body);
|
|
var root = doc.RootElement;
|
|
|
|
if (root.TryGetProperty("data", out var data))
|
|
{
|
|
foreach (var model in data.EnumerateArray())
|
|
{
|
|
var modelId = model.GetProperty("id").GetString() ?? "";
|
|
var maxTokens = 8192;
|
|
if (model.TryGetProperty("max_model_len", out var maxModelLen))
|
|
{
|
|
maxTokens = maxModelLen.GetInt32();
|
|
}
|
|
|
|
models.Add(new ModelInfo
|
|
{
|
|
Id = modelId,
|
|
Endpoint = endpoint,
|
|
MaxTokens = maxTokens
|
|
});
|
|
Console.WriteLine($" - Discovered: {modelId}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($" Error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
static async Task DiscoverAllModels()
|
|
{
|
|
Console.WriteLine("=== Model Discovery ===");
|
|
|
|
// Discover chat/code models
|
|
for (int i = 1; i <= 9999; i++)
|
|
{
|
|
var endpoint = Environment.GetEnvironmentVariable($"MODEL_ENDPOINT_{i}");
|
|
if (string.IsNullOrEmpty(endpoint)) break;
|
|
await DiscoverModelsFromEndpoint(endpoint);
|
|
}
|
|
|
|
// Discover TTS endpoints
|
|
for (int i = 1; i <= 9999; i++)
|
|
{
|
|
var endpoint = Environment.GetEnvironmentVariable($"TTS_ENDPOINT_{i}");
|
|
if (string.IsNullOrEmpty(endpoint)) break;
|
|
Console.WriteLine($"Discovering TTS from: {endpoint}");
|
|
ttsEndpoints.Add(endpoint);
|
|
}
|
|
|
|
Console.WriteLine($"\n{models.Count} model(s) discovered");
|
|
Console.WriteLine($"{ttsEndpoints.Count} TTS endpoint(s) discovered\n");
|
|
}
|
|
|
|
static async Task<string> MakeChatRequest(int modelIdx, string systemMsg, string userMsg, int maxTokens)
|
|
{
|
|
var model = models[modelIdx];
|
|
var url = $"{model.Endpoint}/chat/completions";
|
|
|
|
var payload = new
|
|
{
|
|
model = model.Id,
|
|
messages = new[]
|
|
{
|
|
new { role = "system", content = systemMsg },
|
|
new { role = "user", content = userMsg }
|
|
},
|
|
max_tokens = maxTokens
|
|
};
|
|
|
|
var json = JsonSerializer.Serialize(payload);
|
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
|
|
|
var response = await client.PostAsync(url, content);
|
|
var body = await response.Content.ReadAsStringAsync();
|
|
|
|
using var doc = JsonDocument.Parse(body);
|
|
var root = doc.RootElement;
|
|
return root.GetProperty("choices")[0].GetProperty("message").GetProperty("content").GetString() ?? "";
|
|
}
|
|
|
|
static async Task MakeChatStreamRequest(int modelIdx, string systemMsg, string userMsg, int maxTokens)
|
|
{
|
|
var model = models[modelIdx];
|
|
var url = $"{model.Endpoint}/chat/completions";
|
|
|
|
var payload = new
|
|
{
|
|
model = model.Id,
|
|
messages = new[]
|
|
{
|
|
new { role = "system", content = systemMsg },
|
|
new { role = "user", content = userMsg }
|
|
},
|
|
max_tokens = maxTokens,
|
|
stream = true
|
|
};
|
|
|
|
var json = JsonSerializer.Serialize(payload);
|
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
|
|
|
using var request = new HttpRequestMessage(HttpMethod.Post, url);
|
|
request.Content = content;
|
|
|
|
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
|
using var stream = await response.Content.ReadAsStreamAsync();
|
|
using var reader = new StreamReader(stream);
|
|
|
|
Console.Write("Response: ");
|
|
|
|
while (!reader.EndOfStream)
|
|
{
|
|
var line = await reader.ReadLineAsync();
|
|
if (string.IsNullOrEmpty(line)) continue;
|
|
|
|
if (line.StartsWith("data: "))
|
|
{
|
|
var data = line.Substring(6);
|
|
if (data == "[DONE]") break;
|
|
|
|
try
|
|
{
|
|
using var doc = JsonDocument.Parse(data);
|
|
var root = doc.RootElement;
|
|
if (root.TryGetProperty("choices", out var choices) && choices.GetArrayLength() > 0)
|
|
{
|
|
var choice = choices[0];
|
|
if (choice.TryGetProperty("delta", out var delta))
|
|
{
|
|
if (delta.TryGetProperty("content", out var contentProp))
|
|
{
|
|
var contentStr = contentProp.GetString();
|
|
if (!string.IsNullOrEmpty(contentStr))
|
|
{
|
|
Console.Write(contentStr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Ignore parse errors
|
|
}
|
|
}
|
|
}
|
|
|
|
Console.WriteLine();
|
|
}
|
|
|
|
static async Task<string> MakeTtsRequest(string text)
|
|
{
|
|
if (ttsEndpoints.Count == 0)
|
|
return "ERROR: No TTS endpoints available";
|
|
|
|
var endpoint = ttsEndpoints[0];
|
|
var url = $"{endpoint}/audio/speech";
|
|
|
|
var payload = new
|
|
{
|
|
model = "tts-1",
|
|
voice = "alloy",
|
|
input = text
|
|
};
|
|
|
|
var json = JsonSerializer.Serialize(payload);
|
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
|
|
|
var response = await client.PostAsync(url, content);
|
|
var audioData = await response.Content.ReadAsByteArrayAsync();
|
|
|
|
await File.WriteAllBytesAsync("output.mp3", audioData);
|
|
return $"Audio saved to output.mp3 ({audioData.Length} bytes)";
|
|
}
|
|
|
|
static async Task HermesExample()
|
|
{
|
|
Console.WriteLine("\n=== Non-Streaming Chat (using first discovered model) ===");
|
|
if (models.Count == 0)
|
|
{
|
|
Console.WriteLine("ERROR: No models available");
|
|
return;
|
|
}
|
|
|
|
var model = models[0];
|
|
Console.WriteLine($"Model: {model.Id}");
|
|
Console.WriteLine($"Endpoint: {model.Endpoint}\n");
|
|
|
|
try
|
|
{
|
|
var response = await MakeChatRequest(
|
|
0,
|
|
"You are Hermes, a helpful AI assistant from Nous Research.",
|
|
"Explain quantum computing in one sentence.",
|
|
100
|
|
);
|
|
Console.WriteLine($"Response: {response}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
static async Task QwenStreamExample()
|
|
{
|
|
Console.WriteLine("\n=== Streaming Chat (using second or first model) ===");
|
|
if (models.Count == 0)
|
|
{
|
|
Console.WriteLine("ERROR: No models available");
|
|
return;
|
|
}
|
|
|
|
var modelIdx = models.Count >= 2 ? 1 : 0;
|
|
var model = models[modelIdx];
|
|
Console.WriteLine($"Model: {model.Id}");
|
|
Console.WriteLine($"Endpoint: {model.Endpoint}\n");
|
|
|
|
try
|
|
{
|
|
await MakeChatStreamRequest(
|
|
modelIdx,
|
|
"You are Qwen, a coding assistant specialized in software development.",
|
|
"Write a hello world function in C#.",
|
|
200
|
|
);
|
|
Console.WriteLine();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
static async Task TtsExample()
|
|
{
|
|
Console.WriteLine("\n=== TTS Speech Generation Example ===");
|
|
if (ttsEndpoints.Count == 0)
|
|
{
|
|
Console.WriteLine("ERROR: No TTS endpoints available");
|
|
return;
|
|
}
|
|
|
|
Console.WriteLine($"Endpoint: {ttsEndpoints[0]}\n");
|
|
|
|
try
|
|
{
|
|
var result = await MakeTtsRequest("Hello from C#! This is a text to speech example.");
|
|
Console.WriteLine(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
static async Task Main(string[] args)
|
|
{
|
|
Console.WriteLine("C# AI API Examples (Dynamic Model Discovery)");
|
|
Console.WriteLine("=============================================");
|
|
Console.WriteLine();
|
|
|
|
await DiscoverAllModels();
|
|
|
|
if (models.Count == 0)
|
|
{
|
|
Console.WriteLine("ERROR: No models discovered. Check environment variables:");
|
|
Console.WriteLine(" MODEL_ENDPOINT_1, MODEL_ENDPOINT_2, etc.");
|
|
Environment.Exit(1);
|
|
}
|
|
|
|
await HermesExample();
|
|
await QwenStreamExample();
|
|
await TtsExample();
|
|
}
|
|
}
|