189 lines
7.4 KiB
C#
189 lines
7.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AI.Client
|
|
{
|
|
public class AiClient
|
|
{
|
|
private readonly HttpClient _httpClient;
|
|
private readonly string _baseUrl;
|
|
|
|
public AiClient(string baseUrl = "http://localhost:8080/api")
|
|
{
|
|
_baseUrl = baseUrl.TrimEnd('/');
|
|
_httpClient = new HttpClient();
|
|
_httpClient.Timeout = TimeSpan.FromMinutes(15); // Increased to 15 minutes for long generations
|
|
}
|
|
|
|
// --- CORE COMMANDS ---
|
|
|
|
public async Task<Dictionary<string, InstanceState>> GetInstancesAsync()
|
|
{
|
|
return await GetJsonAsync<Dictionary<string, InstanceState>>("/admin/instances");
|
|
}
|
|
|
|
public async Task<AiResponse> SendPromptAsync(string text, string instanceId = null)
|
|
{
|
|
var payload = new { prompt = text, blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/inject", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> NewChatAsync(string instanceId = null)
|
|
{
|
|
var payload = new { blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/new_chat", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> ToggleUrlContextAsync(bool enabled, string instanceId = null)
|
|
{
|
|
var payload = new { enabled = enabled, blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/toggle_url_context", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> SetResolutionAsync(string level, string instanceId = null)
|
|
{
|
|
var payload = new { level = level, blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/resolution", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> DeleteTurnAsync(int index, string instanceId = null)
|
|
{
|
|
var payload = new { index = index, blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/delete", payload);
|
|
}
|
|
|
|
// --- ADVANCED COMMANDS ---
|
|
|
|
public async Task<AiResponse> SetSettingsAsync(string instanceId, float? temp, float? topP, string model, string sysInst, string thinkingLevel)
|
|
{
|
|
// Use a dictionary to avoid sending null values which might confuse the backend
|
|
var payload = new Dictionary<string, object>();
|
|
if (!string.IsNullOrEmpty(instanceId)) payload["instance_id"] = instanceId;
|
|
if (temp.HasValue) payload["temperature"] = temp.Value;
|
|
if (topP.HasValue) payload["top_p"] = topP.Value;
|
|
if (!string.IsNullOrEmpty(model)) payload["model"] = model;
|
|
if (!string.IsNullOrEmpty(sysInst)) payload["system_instructions"] = sysInst;
|
|
if (!string.IsNullOrEmpty(thinkingLevel)) payload["thinking_level"] = thinkingLevel;
|
|
|
|
payload["blocking"] = true;
|
|
|
|
return await PostJsonAsync<AiResponse>("/admin/action/settings", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> GetSettingsAsync(string instanceId = null)
|
|
{
|
|
var payload = new { blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/get_settings", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> GetChatHistoryAsync(string instanceId = null, bool forceSync = false)
|
|
{
|
|
var payload = new { blocking = true, instance_id = instanceId, force_sync = forceSync };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/get_chat_history", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> CreateShardAsync(string instanceId = null)
|
|
{
|
|
var payload = new { blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/create_shard", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> InjectShardAsync(string shardData, string instanceId = null)
|
|
{
|
|
var payload = new { shard_data = shardData, blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/inject_shard", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> InjectDocAsync(string filename, string content, string instanceId = null)
|
|
{
|
|
var payload = new { filename = filename, content = content, blocking = true, instance_id = instanceId };
|
|
return await PostJsonAsync<AiResponse>("/admin/action/inject_doc", payload);
|
|
}
|
|
|
|
public async Task<AiResponse> SetOpenAISystemInstructionsAsync(string instructions)
|
|
{
|
|
var payload = new { instructions = instructions };
|
|
return await PostJsonAsync<AiResponse>("/admin/openai/system_instructions", payload);
|
|
}
|
|
|
|
// --- INTERNAL HELPERS ---
|
|
|
|
private async Task<T> GetJsonAsync<T>(string endpoint)
|
|
{
|
|
try
|
|
{
|
|
var response = await _httpClient.GetAsync(_baseUrl + endpoint);
|
|
response.EnsureSuccessStatusCode();
|
|
var responseString = await response.Content.ReadAsStringAsync();
|
|
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
|
return JsonSerializer.Deserialize<T>(responseString, options);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"API GET Failed: {ex.Message}", ex);
|
|
}
|
|
}
|
|
|
|
private async Task<T> PostJsonAsync<T>(string endpoint, object data)
|
|
{
|
|
try
|
|
{
|
|
var json = JsonSerializer.Serialize(data);
|
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _httpClient.PostAsync(_baseUrl + endpoint, content);
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
var responseString = await response.Content.ReadAsStringAsync();
|
|
|
|
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
|
return JsonSerializer.Deserialize<T>(responseString, options);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception($"API POST Failed: {ex.Message}", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- DATA MODELS ---
|
|
|
|
public class AiResponse
|
|
{
|
|
public string Status { get; set; }
|
|
public string Task_Id { get; set; }
|
|
public string Instance_Id { get; set; }
|
|
public string Mode { get; set; }
|
|
public string Output { get; set; }
|
|
public string Error { get; set; }
|
|
}
|
|
|
|
public class InstanceState
|
|
{
|
|
public string last_seen { get; set; }
|
|
public string url { get; set; }
|
|
public int turn_count { get; set; }
|
|
public bool is_busy { get; set; }
|
|
}
|
|
|
|
public class AiSettings
|
|
{
|
|
public float? Temperature { get; set; }
|
|
public float? Top_P { get; set; }
|
|
public string Model { get; set; }
|
|
public string Thinking_Level { get; set; }
|
|
public string System_Instructions { get; set; }
|
|
public string Resolution { get; set; }
|
|
public bool? Url_Context { get; set; }
|
|
}
|
|
|
|
public class AiChatTurn
|
|
{
|
|
public string Role { get; set; }
|
|
public string Text { get; set; }
|
|
}
|
|
} |