uncloseai.com/languages/csharp/Uncloseai.cs
Russell Ballestrini 9e3eccb1b9 modified: .gitignore
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
2025-10-14 10:24:16 -04:00

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();
}
}