Ship persona shelves, Exact controls, and overlay author pipeline.

Add Leonid as a shelf-based example with preference_bias slider; support /persona new clone-to-overlay and UI-only delete.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-22 01:48:02 +03:00
co-authored by Cursor
parent ac8e30c7c8
commit cf89348f85
26 changed files with 1311 additions and 102 deletions
+120
View File
@@ -153,6 +153,7 @@ public partial class SwarmAssistentExtension
}
string enrichedContext = InjectMemoryHits(contextJson, hits);
enrichedContext = EnrichPersonaContext(enrichedContext, pid, packName);
List<JObject> messages = BuildOllamaMessages(packName, includeBase, enrichedContext, userMessages, personaId: pid, skillIds: skills);
JArray civitaiResults = [];
string reply = "";
@@ -169,6 +170,7 @@ public partial class SwarmAssistentExtension
(reply, lastRaw) = await CallOllamaChat(root, modelName, messages, stream: onDelta is not null, onDelta, pid);
JObject patch = TryParsePatch(reply);
await ApplyMemoryActions(root, patch, embed, pid);
ApplyPersonaActions(patch, ref pid);
if (hop + 1 >= maxHops)
{
break;
@@ -450,6 +452,124 @@ public partial class SwarmAssistentExtension
return AssistentConfig.SafeId(currentPersonaId) ?? AssistentMemory.SharedPersona;
}
string EnrichPersonaContext(string contextJson, string personaId, string packName)
{
JObject ctx;
try
{
ctx = string.IsNullOrWhiteSpace(contextJson) ? new JObject() : JObject.Parse(contextJson);
}
catch
{
ctx = new JObject { ["_raw_context"] = contextJson };
}
string pid = AssistentConfig.SafeId(personaId) ?? Config.DefaultPersonaId();
ctx["persona_source"] = Config.PersonaSource(pid);
JObject schema = Config.LoadControlsSchema(pid);
JObject values = Config.LoadControlValues(pid);
if (schema.Properties().Any())
{
ctx["persona_controls"] = new JObject
{
["schema"] = schema,
["values"] = values,
};
}
JArray catalog = [];
foreach (var p in Config.ListPersonaCatalog())
{
catalog.Add(new JObject
{
["id"] = p.id,
["title"] = p.title,
["source"] = p.source,
});
}
ctx["personas"] = catalog;
if (string.Equals(packName, "author_persona", StringComparison.OrdinalIgnoreCase)
|| string.Equals(packName, "persona", StringComparison.OrdinalIgnoreCase))
{
JObject shelves = Config.LoadIdentityParts(pid);
shelves.Remove("extra");
ctx["persona_shelves"] = shelves;
ctx["persona_controls_schema"] = schema;
}
return ctx.ToString(Newtonsoft.Json.Formatting.None);
}
/// <summary>Apply overlay persona clone/write from patch. Ignores persona_delete. Updates pid ref after switch.</summary>
void ApplyPersonaActions(JObject patch, ref string personaId)
{
if (patch is null || Config is null)
{
return;
}
// Never honor delete from the model.
bool wantClone = false, wantWrite = false;
if (patch["actions"] is JArray acts)
{
foreach (JToken a in acts)
{
string s = a?.ToString() ?? "";
if (string.Equals(s, "persona_clone", StringComparison.OrdinalIgnoreCase))
{
wantClone = true;
}
if (string.Equals(s, "persona_write", StringComparison.OrdinalIgnoreCase))
{
wantWrite = true;
}
}
}
if (patch["persona_clone"] is JObject)
{
wantClone = true;
}
if (patch["persona_shelves"] is JObject)
{
wantWrite = true;
}
try
{
if (wantClone && patch["persona_clone"] is JObject clone)
{
string from = AssistentConfig.SafeId(clone["from"]?.ToString()) ?? personaId;
string to = AssistentConfig.SafeId(clone["to"]?.ToString());
string title = clone["title"]?.ToString();
bool overwrite = clone["overwrite"]?.Value<bool?>() == true;
if (to is not null)
{
Config.ClonePersonaToOverlay(from, to, title, overwrite);
personaId = to;
patch["_persona_cloned"] = to;
}
}
if (wantWrite && patch["persona_shelves"] is JObject shelves)
{
string target = AssistentConfig.SafeId(patch["persona"]?.ToString())
?? AssistentConfig.SafeId(patch["persona_clone"]?["to"]?.ToString())
?? personaId;
if (target is not null)
{
Config.SavePersonaShelves(target, shelves);
patch["_persona_written"] = target;
}
}
// Control values from model patch (Exact).
if (patch["controls"] is JObject ctrlVals)
{
string ctrlPid = AssistentConfig.SafeId(patch["persona"]?.ToString()) ?? personaId;
Config.SaveControlValues(ctrlPid, ctrlVals);
patch["_controls_saved"] = true;
}
}
catch (Exception ex)
{
Logs.Warning($"Assistent persona actions: {ex.Message}");
patch["_persona_error"] = ex.Message;
}
}
async Task ApplyMemoryActions(string root, JObject patch, string embedModel, string personaId)
{
if (patch is null || Memory is null)