add configuration profiles with per-invocation --profile flag

- Add SystemPrompt field to HushConfig (empty = built-in default)
- Refactor ConfigManager: extract ApplyTomlFields, add LoadWithProfile(),
  ListProfiles(), GetProfilePath(), EnsureProfilesDirExists(); remove
  HUSH_PROFILE env-var logic (profiles are now resolved by the CLI)
- Extend socket protocol: action commands (START/STOP/TOGGLE/ABORT) now
  carry a [4-byte LE length][optional HushConfig JSON] payload so the CLI
  can pass a per-invocation config override without restarting the daemon
- Add GENERATE_PROFILE (cmd 7) socket command: CLI sends a description,
  daemon calls the LLM and returns a generated system prompt
- Orchestrator: StopAndProcessAsync accepts optional HushConfig override;
  ProcessWithLlmAsync uses proper system/user chat roles and respects
  config.SystemPrompt; add GenerateProfilePromptAsync
- Split CompleteTextAsync signature to (systemPrompt, userMessage, model)
  across ITextStreamingProvider, GroqProvider, FireworksProvider
- Add --profile/-p flag to hush toggle and hush stop
- Add hush profiles subcommand: list, get, new (manual or AI-generated), edit
This commit is contained in:
2026-03-23 00:38:29 +01:00
parent 70e784a1cc
commit eb0619dea2
14 changed files with 659 additions and 372 deletions
+17 -1
View File
@@ -1,4 +1,5 @@
using System.CommandLine;
using Hush.Config;
using Hush.Daemon;
using Spectre.Console;
@@ -9,13 +10,28 @@ public static class StopCommand
public static Command Create()
{
var command = new Command("stop", "Stop recording and process");
var profileOption = new Option<string?>(["--profile", "-p"], "Profile name to apply when processing");
command.AddOption(profileOption);
command.SetHandler(async (context) =>
{
var profileName = context.ParseResult.GetValueForOption(profileOption);
try
{
await using var client = new SocketClient();
await client.ConnectAsync(TimeSpan.FromSeconds(2));
await client.SendCommandAsync(DaemonProtocol.STOP);
if (!string.IsNullOrEmpty(profileName))
{
var config = new ConfigManager().LoadWithProfile(profileName);
await client.SendCommandWithConfigAsync(DaemonProtocol.STOP, config);
}
else
{
await client.SendCommandAsync(DaemonProtocol.STOP);
}
AnsiConsole.MarkupLine("[green]Stop command sent[/]");
}
catch (Exception ex)