Motori multipli: Codex e interruttore CLI nelle Impostazioni
Introduce l'astrazione Engine (Claude Code, Codex) con argomenti e parser propri e EngineRunner come unico punto di avvio, al posto di Claude.cs. Il JSON delle chat salva motore e id di sessione (i file vecchi restano chat di Claude Code). Cambiare CLI apre una nuova chat; modelli ed effort seguono il motore; un motore non installato non è selezionabile. La CLI accetta --engine <id>. Codex gira in sola lettura e la sessione si legge da thread.started. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c50bd63723
commit
e60d64ed58
6 files changed
+349
-34
No files matched your search
@@ -0,0 +1,50 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AgentWikiUi.Core;
|
||||
|
||||
// Unico punto di avvio dei motori, condiviso da CLI e GUI.
|
||||
static class EngineRunner
|
||||
{
|
||||
public static ProcessStartInfo CreateStart(Engine engine, string prompt, bool captured, string? sessionId = null, bool resume = false, string model = "", string effort = "")
|
||||
{
|
||||
var psi = new ProcessStartInfo(engine.Executable)
|
||||
{
|
||||
WorkingDirectory = AppContext.BaseDirectory, // mai la cwd del chiamante né Assembly.Location (vuoto in single-file)
|
||||
UseShellExecute = false,
|
||||
RedirectStandardInput = true, // chiuso subito dal chiamante: evita l'attesa di stdin del motore
|
||||
RedirectStandardOutput = captured,
|
||||
RedirectStandardError = captured,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
foreach (var a in engine.BuildArgs(prompt, sessionId, resume, model, effort, structured: captured)) psi.ArgumentList.Add(a);
|
||||
return psi;
|
||||
}
|
||||
|
||||
// CLI: stdout/stderr ereditati (streaming), exit code propagato, 127 se l'eseguibile manca.
|
||||
public static int RunInherited(Engine engine, string prompt)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var p = Process.Start(CreateStart(engine, prompt, captured: false))!;
|
||||
p.StandardInput.Close();
|
||||
p.WaitForExit();
|
||||
return p.ExitCode;
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
Console.Error.WriteLine($"'{engine.Executable}' non trovato nel PATH.");
|
||||
return 127;
|
||||
}
|
||||
}
|
||||
|
||||
// GUI: output catturato e interpretato dal motore. Win32Exception se l'eseguibile non è nel PATH.
|
||||
public static async Task<EngineReply> RunCapturedAsync(Engine engine, string prompt, string? sessionId, bool resume, string model, string effort)
|
||||
{
|
||||
using var p = Process.Start(CreateStart(engine, prompt, captured: true, sessionId, resume, model, effort))!;
|
||||
p.StandardInput.Close();
|
||||
var o = p.StandardOutput.ReadToEndAsync();
|
||||
var e = p.StandardError.ReadToEndAsync();
|
||||
await p.WaitForExitAsync();
|
||||
return engine.Parse(p.ExitCode, await o, await e);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user