Add OpenRouter chat provider; fix Windows load errors (0.17.0).
- 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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f2b92e96ca
commit
d67f5e396e
+30
-2
@@ -117,7 +117,10 @@ public sealed class AssistentConfig
|
||||
}
|
||||
try
|
||||
{
|
||||
return JObject.Parse(File.ReadAllText(path, Encoding.UTF8));
|
||||
// Share read/write/delete: Windows otherwise fails a concurrent SaveSettings with a sharing violation.
|
||||
using FileStream fs = new(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
|
||||
using StreamReader reader = new(fs, Encoding.UTF8);
|
||||
return JObject.Parse(reader.ReadToEnd());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -1671,7 +1674,32 @@ public sealed class AssistentConfig
|
||||
Directory.CreateDirectory(_overlayRoot);
|
||||
string path = Path.Combine(_overlayRoot, "settings.json");
|
||||
JObject merged = DeepMerge(LoadSettings(), settings ?? new JObject());
|
||||
File.WriteAllText(path, merged.ToString(Newtonsoft.Json.Formatting.Indented), Encoding.UTF8);
|
||||
WriteFileAtomic(path, merged.ToString(Newtonsoft.Json.Formatting.Indented));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Temp file + rename, retried briefly: readers never see a half-written file and a
|
||||
/// transient lock (antivirus, editor, parallel read) does not fail the API call.</summary>
|
||||
static void WriteFileAtomic(string path, string text)
|
||||
{
|
||||
string tmp = $"{path}.{Guid.NewGuid():N}.tmp";
|
||||
File.WriteAllText(tmp, text, Encoding.UTF8);
|
||||
for (int attempt = 0; ; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Move(tmp, path, overwrite: true);
|
||||
return;
|
||||
}
|
||||
catch (IOException) when (attempt < 10)
|
||||
{
|
||||
System.Threading.Thread.Sleep(25 * (attempt + 1));
|
||||
}
|
||||
catch
|
||||
{
|
||||
try { File.Delete(tmp); } catch { }
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user