- OpenRouter as an alternative chat provider: server-side API key (settings.json or OPENROUTER_API_KEY), model list with vision marks and filter, SSE streaming, images as data URLs. Memory embeddings stay on Ollama; park/warm LLM are no-ops for the remote provider. - AssistentSaveKnowledgeAttach: JArray param is not supported by SwarmUI API reflection and aborted registration of every later API call; use string[]. - SQLite bootstrap: preload native e_sqlite3 for the current OS/arch (win/osx/linux) and resolve DllImport to it. - settings.json: shared-read + atomic write with retry to avoid Windows sharing violations. - csproj: fix MSB4012 in the native SQLite copy target. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
131 lines
4.4 KiB
C#
131 lines
4.4 KiB
C#
using System.Threading.Tasks;
|
|
using Newtonsoft.Json.Linq;
|
|
using SwarmUI.Accounts;
|
|
|
|
namespace Mrleo1nid.SwarmAssistent;
|
|
|
|
public partial class SwarmAssistentExtension
|
|
{
|
|
public async Task<JObject> AssistentListKnowledgeCatalog(Session session, string persona = null)
|
|
{
|
|
await Task.CompletedTask;
|
|
if (Memory is null)
|
|
{
|
|
return new JObject { ["error"] = "memory not ready" };
|
|
}
|
|
try
|
|
{
|
|
Memory.EnsureBooksIndex();
|
|
string pid = AssistentConfig.SafeId(persona) ?? Config.DefaultPersonaId();
|
|
return new JObject
|
|
{
|
|
["success"] = true,
|
|
["knowledge"] = BuildKnowledgeCatalog(pid),
|
|
["editable"] = Config.IsOverlayPersona(pid) && !Config.IsProtectedPersona(pid),
|
|
};
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
return new JObject { ["error"] = $"knowledge catalog: {ex.Message}" };
|
|
}
|
|
}
|
|
|
|
public async Task<JObject> AssistentSearchKnowledge(Session session, string query, string persona = null, int limit = 8, string rating = null, string book = null)
|
|
{
|
|
await Task.CompletedTask;
|
|
if (Memory is null)
|
|
{
|
|
return new JObject { ["error"] = "memory not ready" };
|
|
}
|
|
query = (query ?? "").Trim();
|
|
if (query.Length < 1)
|
|
{
|
|
return new JObject { ["error"] = "query required" };
|
|
}
|
|
try
|
|
{
|
|
string pid = AssistentConfig.SafeId(persona) ?? Config.DefaultPersonaId();
|
|
JArray results;
|
|
if (!string.IsNullOrWhiteSpace(book))
|
|
{
|
|
results = Memory.LookupBooks(query, limit, [book.Trim()], rating);
|
|
}
|
|
else
|
|
{
|
|
results = SearchKnowledge(pid, query, limit, rating);
|
|
}
|
|
return new JObject
|
|
{
|
|
["success"] = true,
|
|
["query"] = query,
|
|
["persona"] = pid,
|
|
["results"] = results,
|
|
["civitai_results"] = CivitaiResultsShim(results),
|
|
};
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
return new JObject { ["error"] = $"knowledge search: {ex.Message}" };
|
|
}
|
|
}
|
|
|
|
public async Task<JObject> AssistentGetKnowledgeAttach(Session session, string persona = null)
|
|
{
|
|
await Task.CompletedTask;
|
|
string pid = AssistentConfig.SafeId(persona) ?? Config.DefaultPersonaId();
|
|
return new JObject
|
|
{
|
|
["success"] = true,
|
|
["persona"] = pid,
|
|
["attach"] = new JArray(ResolveAttachedBooks(pid)),
|
|
["editable"] = Config.IsOverlayPersona(pid) && !Config.IsProtectedPersona(pid),
|
|
["source"] = Config.PersonaSource(pid),
|
|
};
|
|
}
|
|
|
|
/// <remarks>SwarmUI's API reflection has no JArray coercer — <c>string[]</c> is the supported list type.</remarks>
|
|
public async Task<JObject> AssistentSaveKnowledgeAttach(Session session, string persona, string[] attach = null)
|
|
{
|
|
await Task.CompletedTask;
|
|
string pid = AssistentConfig.SafeId(persona);
|
|
if (pid is null)
|
|
{
|
|
return new JObject { ["error"] = "persona required" };
|
|
}
|
|
if (Config.IsProtectedPersona(pid))
|
|
{
|
|
return new JObject { ["error"] = "bundled/pack personas cannot edit attach here — clone to overlay first" };
|
|
}
|
|
if (!Config.IsOverlayPersona(pid))
|
|
{
|
|
return new JObject { ["error"] = "overlay persona required" };
|
|
}
|
|
try
|
|
{
|
|
JArray cleaned = [];
|
|
if (attach is not null)
|
|
{
|
|
foreach (string t in attach)
|
|
{
|
|
string id = AssistentConfig.SafeId(t);
|
|
if (id is not null)
|
|
{
|
|
cleaned.Add(id);
|
|
}
|
|
}
|
|
}
|
|
Config.SaveKnowledgeAttachOverlay(pid, cleaned);
|
|
return new JObject
|
|
{
|
|
["success"] = true,
|
|
["persona"] = pid,
|
|
["attach"] = new JArray(ResolveAttachedBooks(pid)),
|
|
};
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
return new JObject { ["error"] = $"save knowledge attach: {ex.Message}" };
|
|
}
|
|
}
|
|
}
|