Ship Assistent 0.10: settings panel and UserPrefs with prompt weight.

Separate About-the-user memory (global + per-persona) from craft RAG, add tabbed settings with persona export/import and craft clear APIs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-22 02:05:12 +03:00
co-authored by Cursor
parent cf89348f85
commit fa73158e1c
18 changed files with 2081 additions and 191 deletions
+116
View File
@@ -139,4 +139,120 @@ public partial class SwarmAssistentExtension
return new JObject { ["error"] = ex.Message };
}
}
public async Task<JObject> 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<JObject> 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<JObject> 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}" };
}
}
}