using System; using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using SwarmUI.Accounts; using SwarmUI.Utils; namespace Mrleo1nid.SwarmAssistent; /// Persona overlay CRUD: controls Exact, clone/write shelves, UI-only delete. public partial class SwarmAssistentExtension { public async Task AssistentSaveControls(Session session, string persona = null, JObject controls = null) { await Task.CompletedTask; string pid = AssistentConfig.SafeId(persona) ?? Config.DefaultPersonaId(); try { JObject saved = Config.SaveControlValues(pid, controls ?? new JObject()); return new JObject { ["success"] = true, ["persona"] = pid, ["control_values"] = saved, ["controls"] = Config.LoadControlsSchema(pid), }; } catch (Exception ex) { return new JObject { ["error"] = $"controls save: {ex.Message}" }; } } public async Task AssistentGetPersonaShelves(Session session, string persona = null) { await Task.CompletedTask; string pid = AssistentConfig.SafeId(persona) ?? Config.DefaultPersonaId(); return new JObject { ["success"] = true, ["persona"] = pid, ["source"] = Config.PersonaSource(pid), ["shelves"] = Config.LoadIdentityParts(pid), ["controls"] = Config.LoadControlsSchema(pid), ["control_values"] = Config.LoadControlValues(pid), ["identity_summary"] = Config.RenderIdentityBlock(pid), }; } public async Task AssistentClonePersona(Session session, string from = null, string to = null, string title = null, bool overwrite = false) { await Task.CompletedTask; string src = AssistentConfig.SafeId(from) ?? Config.DefaultPersonaId(); string dest = AssistentConfig.SafeId(to); if (dest is null) { return new JObject { ["error"] = "invalid to id" }; } try { JObject meta = Config.ClonePersonaToOverlay(src, dest, title, overwrite); return new JObject { ["success"] = true, ["persona"] = meta, ["personas"] = new JArray(Config.ListPersonaCatalog().Select(p => new JObject { ["id"] = p.id, ["title"] = p.title, ["accent"] = p.accent, ["source"] = p.source, })), }; } catch (Exception ex) { return new JObject { ["error"] = ex.Message }; } } public async Task AssistentSavePersona(Session session, string persona = null, JObject shelves = null) { await Task.CompletedTask; string pid = AssistentConfig.SafeId(persona); if (pid is null) { return new JObject { ["error"] = "invalid persona id" }; } try { JObject saved = Config.SavePersonaShelves(pid, shelves); return new JObject { ["success"] = true, ["persona"] = pid, ["source"] = Config.PersonaSource(pid), ["shelves"] = saved, }; } catch (Exception ex) { return new JObject { ["error"] = ex.Message }; } } /// UI-only. Never called from LLM patch actions. public async Task AssistentDeletePersona(Session session, string persona = null) { await Task.CompletedTask; string pid = AssistentConfig.SafeId(persona); if (pid is null) { return new JObject { ["error"] = "invalid persona id" }; } if (!Config.IsOverlayPersona(pid)) { return new JObject { ["error"] = "only overlay personas can be deleted" }; } try { bool ok = Config.DeleteOverlayPersona(pid); string next = Config.DefaultPersonaId(); return new JObject { ["success"] = ok, ["deleted"] = pid, ["default_persona"] = next, ["personas"] = new JArray(Config.ListPersonaCatalog().Select(p => new JObject { ["id"] = p.id, ["title"] = p.title, ["accent"] = p.accent, ["source"] = p.source, })), }; } catch (Exception ex) { return new JObject { ["error"] = ex.Message }; } } public async Task AssistentExportPersona(Session session, string persona = null) { await Task.CompletedTask; string pid = AssistentConfig.SafeId(persona) ?? Config.DefaultPersonaId(); try { JObject pack = Config.ExportPersonaPack(pid); return new JObject { ["success"] = true, ["pack"] = pack }; } catch (Exception ex) { return new JObject { ["error"] = $"export persona: {ex.Message}" }; } } public async Task AssistentImportPersona(Session session, JObject pack = null, string new_id = null, bool overwrite = false) { await Task.CompletedTask; try { JObject meta = Config.ImportPersonaPack(pack, new_id, overwrite); return new JObject { ["success"] = true, ["persona"] = meta, ["personas"] = new JArray(Config.ListPersonaCatalog().Select(p => new JObject { ["id"] = p.id, ["title"] = p.title, ["accent"] = p.accent, ["source"] = p.source, })), }; } catch (Exception ex) { return new JObject { ["error"] = ex.Message }; } } public async Task AssistentSaveKnobs(Session session, JObject assistant = null, JObject exact = null) { await Task.CompletedTask; try { JObject asstOut = null; JObject exactOut = null; if (assistant is not null && assistant.Count > 0) { JObject sparse = new(); foreach (string key in new[] { "num_ctx", "history_keep_turns", "memory_top_k", "user_prefs_weight", "user_prefs_max" }) { if (assistant[key] is not null) { sparse[key] = assistant[key]; } } if (sparse.Count > 0) { asstOut = Config.MergeOverlayBaseJson("assistant.json", sparse); } } if (exact is not null && exact.Count > 0) { JObject sparse = new(); if (exact["profiles"] is JObject profiles) { JObject slimProfiles = new(); foreach (string name in new[] { "turbo", "raw" }) { if (profiles[name] is JObject p) { JObject slim = new(); foreach (string k in new[] { "steps", "cfg", "sigma_shift" }) { if (p[k] is not null) { slim[k] = p[k]; } } if (slim.Count > 0) { slimProfiles[name] = slim; } } } if (slimProfiles.Count > 0) { sparse["profiles"] = slimProfiles; } } if (exact["generation"] is JObject gen) { sparse["generation"] = gen; } if (sparse.Count > 0) { exactOut = Config.MergeOverlayBaseJson("exact.json", sparse); } } string pid = Config.DefaultPersonaId(); return new JObject { ["success"] = true, ["assistant"] = Config.LoadAssistant(pid), ["exact"] = Config.LoadExact(pid), ["overlay_assistant"] = asstOut, ["overlay_exact"] = exactOut, }; } catch (Exception ex) { return new JObject { ["error"] = $"save knobs: {ex.Message}" }; } } }