Refactor code structure and optimize performance across multiple modules
This commit is contained in:
303
src/Cli/StellaOps.Cli/Commands/ModelCommandGroup.cs
Normal file
303
src/Cli/StellaOps.Cli/Commands/ModelCommandGroup.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
using System.CommandLine;
|
||||
using StellaOps.Cli.Extensions;
|
||||
|
||||
namespace StellaOps.Cli.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// CLI commands for AI model bundle management.
|
||||
/// Sprint: SPRINT_20251226_019_AI_offline_inference
|
||||
/// Task: OFFLINE-13, OFFLINE-14
|
||||
/// </summary>
|
||||
internal static class ModelCommandGroup
|
||||
{
|
||||
internal static Command BuildModelCommand(
|
||||
IServiceProvider services,
|
||||
Option<bool> verboseOption,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var model = new Command("model", "AI model bundle management for offline inference.");
|
||||
|
||||
model.Add(BuildModelListCommand(services, verboseOption, cancellationToken));
|
||||
model.Add(BuildModelPullCommand(services, verboseOption, cancellationToken));
|
||||
model.Add(BuildModelVerifyCommand(services, verboseOption, cancellationToken));
|
||||
model.Add(BuildModelInfoCommand(services, verboseOption, cancellationToken));
|
||||
model.Add(BuildModelRemoveCommand(services, verboseOption, cancellationToken));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
private static Command BuildModelListCommand(
|
||||
IServiceProvider services,
|
||||
Option<bool> verboseOption,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var bundlePathOption = new Option<string?>("--bundle-path", new[] { "-p" })
|
||||
{
|
||||
Description = "Path to model bundles directory (defaults to ~/.stellaops/models)."
|
||||
};
|
||||
|
||||
var outputOption = new Option<string?>("--output", new[] { "-o" })
|
||||
{
|
||||
Description = "Output format: table (default), json."
|
||||
}.SetDefaultValue("table").FromAmong("table", "json");
|
||||
|
||||
var command = new Command("list", "List available model bundles.")
|
||||
{
|
||||
bundlePathOption,
|
||||
outputOption,
|
||||
verboseOption
|
||||
};
|
||||
|
||||
command.SetAction(async parseResult =>
|
||||
{
|
||||
var bundlePath = parseResult.GetValue(bundlePathOption);
|
||||
var output = parseResult.GetValue(outputOption) ?? "table";
|
||||
var verbose = parseResult.GetValue(verboseOption);
|
||||
|
||||
await CommandHandlers.HandleModelListAsync(
|
||||
services,
|
||||
bundlePath,
|
||||
output,
|
||||
verbose,
|
||||
cancellationToken);
|
||||
});
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private static Command BuildModelPullCommand(
|
||||
IServiceProvider services,
|
||||
Option<bool> verboseOption,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var modelNameArg = new Argument<string>("model-name")
|
||||
{
|
||||
Description = "Model name to pull (e.g., llama3-8b, mistral-7b, phi-3)."
|
||||
};
|
||||
|
||||
var quantOption = new Option<string?>("--quant", new[] { "-q" })
|
||||
{
|
||||
Description = "Quantization level (e.g., Q4_K_M, Q5_K_M, FP16)."
|
||||
}.SetDefaultValue("Q4_K_M");
|
||||
|
||||
var offlineOption = new Option<bool>("--offline")
|
||||
{
|
||||
Description = "Pull from local cache or USB transfer (no network)."
|
||||
};
|
||||
|
||||
var sourceOption = new Option<string?>("--source", new[] { "-s" })
|
||||
{
|
||||
Description = "Source path for offline pull (USB mount, network share)."
|
||||
};
|
||||
|
||||
var bundlePathOption = new Option<string?>("--bundle-path", new[] { "-p" })
|
||||
{
|
||||
Description = "Destination path for model bundles (defaults to ~/.stellaops/models)."
|
||||
};
|
||||
|
||||
var verifyOption = new Option<bool>("--verify")
|
||||
{
|
||||
Description = "Verify bundle integrity after pull."
|
||||
}.SetDefaultValue(true);
|
||||
|
||||
var outputOption = new Option<string?>("--output", new[] { "-o" })
|
||||
{
|
||||
Description = "Output format: table (default), json."
|
||||
}.SetDefaultValue("table").FromAmong("table", "json");
|
||||
|
||||
var command = new Command("pull", "Pull a model bundle for offline inference.")
|
||||
{
|
||||
modelNameArg,
|
||||
quantOption,
|
||||
offlineOption,
|
||||
sourceOption,
|
||||
bundlePathOption,
|
||||
verifyOption,
|
||||
outputOption,
|
||||
verboseOption
|
||||
};
|
||||
|
||||
command.SetAction(async parseResult =>
|
||||
{
|
||||
var modelName = parseResult.GetValue(modelNameArg) ?? string.Empty;
|
||||
var quant = parseResult.GetValue(quantOption) ?? "Q4_K_M";
|
||||
var offline = parseResult.GetValue(offlineOption);
|
||||
var source = parseResult.GetValue(sourceOption);
|
||||
var bundlePath = parseResult.GetValue(bundlePathOption);
|
||||
var verify = parseResult.GetValue(verifyOption);
|
||||
var output = parseResult.GetValue(outputOption) ?? "table";
|
||||
var verbose = parseResult.GetValue(verboseOption);
|
||||
|
||||
await CommandHandlers.HandleModelPullAsync(
|
||||
services,
|
||||
modelName,
|
||||
quant,
|
||||
offline,
|
||||
source,
|
||||
bundlePath,
|
||||
verify,
|
||||
output,
|
||||
verbose,
|
||||
cancellationToken);
|
||||
});
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private static Command BuildModelVerifyCommand(
|
||||
IServiceProvider services,
|
||||
Option<bool> verboseOption,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var modelNameArg = new Argument<string>("model-name")
|
||||
{
|
||||
Description = "Model name or path to verify."
|
||||
};
|
||||
|
||||
var bundlePathOption = new Option<string?>("--bundle-path", new[] { "-p" })
|
||||
{
|
||||
Description = "Path to model bundles directory (defaults to ~/.stellaops/models)."
|
||||
};
|
||||
|
||||
var checkSignatureOption = new Option<bool>("--check-signature")
|
||||
{
|
||||
Description = "Verify cryptographic signature on the bundle."
|
||||
}.SetDefaultValue(true);
|
||||
|
||||
var trustRootOption = new Option<string?>("--trust-root")
|
||||
{
|
||||
Description = "Path to trust root public key for signature verification."
|
||||
};
|
||||
|
||||
var outputOption = new Option<string?>("--output", new[] { "-o" })
|
||||
{
|
||||
Description = "Output format: table (default), json."
|
||||
}.SetDefaultValue("table").FromAmong("table", "json");
|
||||
|
||||
var command = new Command("verify", "Verify model bundle integrity and signature.")
|
||||
{
|
||||
modelNameArg,
|
||||
bundlePathOption,
|
||||
checkSignatureOption,
|
||||
trustRootOption,
|
||||
outputOption,
|
||||
verboseOption
|
||||
};
|
||||
|
||||
command.SetAction(async parseResult =>
|
||||
{
|
||||
var modelName = parseResult.GetValue(modelNameArg) ?? string.Empty;
|
||||
var bundlePath = parseResult.GetValue(bundlePathOption);
|
||||
var checkSignature = parseResult.GetValue(checkSignatureOption);
|
||||
var trustRoot = parseResult.GetValue(trustRootOption);
|
||||
var output = parseResult.GetValue(outputOption) ?? "table";
|
||||
var verbose = parseResult.GetValue(verboseOption);
|
||||
|
||||
await CommandHandlers.HandleModelVerifyAsync(
|
||||
services,
|
||||
modelName,
|
||||
bundlePath,
|
||||
checkSignature,
|
||||
trustRoot,
|
||||
output,
|
||||
verbose,
|
||||
cancellationToken);
|
||||
});
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private static Command BuildModelInfoCommand(
|
||||
IServiceProvider services,
|
||||
Option<bool> verboseOption,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var modelNameArg = new Argument<string>("model-name")
|
||||
{
|
||||
Description = "Model name to get information for."
|
||||
};
|
||||
|
||||
var bundlePathOption = new Option<string?>("--bundle-path", new[] { "-p" })
|
||||
{
|
||||
Description = "Path to model bundles directory (defaults to ~/.stellaops/models)."
|
||||
};
|
||||
|
||||
var outputOption = new Option<string?>("--output", new[] { "-o" })
|
||||
{
|
||||
Description = "Output format: table (default), json."
|
||||
}.SetDefaultValue("table").FromAmong("table", "json");
|
||||
|
||||
var command = new Command("info", "Display model bundle metadata and requirements.")
|
||||
{
|
||||
modelNameArg,
|
||||
bundlePathOption,
|
||||
outputOption,
|
||||
verboseOption
|
||||
};
|
||||
|
||||
command.SetAction(async parseResult =>
|
||||
{
|
||||
var modelName = parseResult.GetValue(modelNameArg) ?? string.Empty;
|
||||
var bundlePath = parseResult.GetValue(bundlePathOption);
|
||||
var output = parseResult.GetValue(outputOption) ?? "table";
|
||||
var verbose = parseResult.GetValue(verboseOption);
|
||||
|
||||
await CommandHandlers.HandleModelInfoAsync(
|
||||
services,
|
||||
modelName,
|
||||
bundlePath,
|
||||
output,
|
||||
verbose,
|
||||
cancellationToken);
|
||||
});
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private static Command BuildModelRemoveCommand(
|
||||
IServiceProvider services,
|
||||
Option<bool> verboseOption,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var modelNameArg = new Argument<string>("model-name")
|
||||
{
|
||||
Description = "Model name to remove."
|
||||
};
|
||||
|
||||
var bundlePathOption = new Option<string?>("--bundle-path", new[] { "-p" })
|
||||
{
|
||||
Description = "Path to model bundles directory (defaults to ~/.stellaops/models)."
|
||||
};
|
||||
|
||||
var forceOption = new Option<bool>("--force", new[] { "-f" })
|
||||
{
|
||||
Description = "Force removal without confirmation."
|
||||
};
|
||||
|
||||
var command = new Command("remove", "Remove a model bundle.")
|
||||
{
|
||||
modelNameArg,
|
||||
bundlePathOption,
|
||||
forceOption,
|
||||
verboseOption
|
||||
};
|
||||
|
||||
command.SetAction(async parseResult =>
|
||||
{
|
||||
var modelName = parseResult.GetValue(modelNameArg) ?? string.Empty;
|
||||
var bundlePath = parseResult.GetValue(bundlePathOption);
|
||||
var force = parseResult.GetValue(forceOption);
|
||||
var verbose = parseResult.GetValue(verboseOption);
|
||||
|
||||
await CommandHandlers.HandleModelRemoveAsync(
|
||||
services,
|
||||
modelName,
|
||||
bundlePath,
|
||||
force,
|
||||
verbose,
|
||||
cancellationToken);
|
||||
});
|
||||
|
||||
return command;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user