reformatting

This commit is contained in:
grimsace
2026-06-08 15:53:40 -05:00
parent 99df32cb1f
commit ba5e1ff154
16 changed files with 137 additions and 17 deletions
+12
View File
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace finder2e_foundry_converter.Services
{
public interface ILlmService
{
Task<List<string>> GetModelsAsync(string baseUrl);
Task<string> GenerateResponseAsync(string baseUrl, string model, string text, List<string> imagePaths);
}
}
+108
View File
@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;
using System.Text.Json.Serialization;
namespace finder2e_foundry_converter.Services
{
public class LmStudioService : ILlmService
{
private readonly HttpClient _httpClient = new HttpClient();
public async Task<List<string>> GetModelsAsync(string baseUrl)
{
try
{
var response = await _httpClient.GetFromJsonAsync<ModelsResponse>($"{baseUrl.TrimEnd('/')}/v1/models");
if (response?.Data == null) return new List<string>();
var models = new List<string>();
foreach (var model in response.Data)
{
models.Add(model.Id);
}
return models;
}
catch
{
return new List<string> { "Error: LM Studio not found" };
}
}
public async Task<string> GenerateResponseAsync(string baseUrl, string model, string text, List<string> imagePaths)
{
try
{
var contents = new List<object>
{
new { type = "text", text = text }
};
foreach (var path in imagePaths)
{
if (string.IsNullOrWhiteSpace(path)) continue;
var bytes = await System.IO.File.ReadAllBytesAsync(path);
var base64 = Convert.ToBase64String(bytes);
var extension = System.IO.Path.GetExtension(path).ToLower();
var mimeType = extension switch
{
".jpg" or ".jpeg" => "image/jpeg",
".webp" => "image/webp",
_ => "image/png"
};
contents.Add(new
{
type = "image_url",
image_url = new { url = $"data:{mimeType};base64,{base64}" }
});
}
var requestBody = new
{
model = model,
messages = new[]
{
new { role = "user", content = contents }
}
};
var response = await _httpClient.PostAsJsonAsync($"{baseUrl.TrimEnd('/')}/v1/chat/completions", requestBody);
var body = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(body);
if (doc.RootElement.TryGetProperty("error", out var error))
{
return $"Error: {error.GetProperty("message").GetString()}";
}
if (doc.RootElement.TryGetProperty("choices", out var choices) && choices.GetArrayLength() > 0)
{
return choices[0].GetProperty("message").GetProperty("content").GetString() ?? "No content returned";
}
return "No response choices returned.";
}
catch (Exception ex)
{
return $"Error: {ex.Message}";
}
}
private class ModelsResponse
{
[JsonPropertyName("data")]
public List<ModelData>? Data { get; set; }
}
private class ModelData
{
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;
}
}
}
+87
View File
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;
using System.Text.Json.Serialization;
using System.Linq;
namespace finder2e_foundry_converter.Services
{
public class OllamaService : ILlmService
{
private readonly HttpClient _httpClient = new HttpClient();
public async Task<List<string>> GetModelsAsync(string baseUrl)
{
try
{
var response = await _httpClient.GetFromJsonAsync<OllamaModelsResponse>($"{baseUrl.TrimEnd('/')}/api/tags");
if (response?.Models == null) return new List<string>();
return response.Models.Select(m => m.Name).ToList();
}
catch
{
return new List<string> { "Error: Ollama not found" };
}
}
public async Task<string> GenerateResponseAsync(string baseUrl, string model, string text, List<string> imagePaths)
{
try
{
var images = new List<string>();
foreach (var path in imagePaths)
{
if (string.IsNullOrWhiteSpace(path)) continue;
var bytes = await System.IO.File.ReadAllBytesAsync(path);
images.Add(Convert.ToBase64String(bytes));
}
var requestBody = new
{
model = model,
messages = new[]
{
new { role = "user", content = text, images = images.Count > 0 ? images.ToArray() : null }
},
stream = false
};
var response = await _httpClient.PostAsJsonAsync($"{baseUrl.TrimEnd('/')}/api/chat", requestBody);
var body = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(body);
if (doc.RootElement.TryGetProperty("error", out var error))
{
return $"Error: {error.GetString()}";
}
if (doc.RootElement.TryGetProperty("message", out var message))
{
return message.GetProperty("content").GetString() ?? "No content returned";
}
return "No response returned.";
}
catch (Exception ex)
{
return $"Error: {ex.Message}";
}
}
private class OllamaModelsResponse
{
[JsonPropertyName("models")]
public List<OllamaModelData>? Models { get; set; }
}
private class OllamaModelData
{
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
}
}
}