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