mirror of
https://github.com/cloudstack-llc/mlx-knife.git
synced 2026-08-27 02:01:29 -04:00
c5777a3e7a
Session 2 Achievements (100% Complete): • All 5 operations implemented: list, health, show, pull, rm • CLI compatibility: fuzzy matching, @hash syntax, short names • Lock detection: New safety feature replacing interactive prompts • Pull corruption recovery: Clean rm→pull workflow • Hash fuzzy matching: show "model@3df9bfd" works with short hashes Session 3 Major Progress (70% Complete): • JSON API Specification v0.1.1: Complete and production-ready • Full SHA hashes: 40-char hashes in list output for broke-cluster • Show command: --files and --config options fully implemented • JSON-flag enforcement: --json required in alpha for correct usage Key Features: • Broke-cluster integration ready with enforced --json flag • Real-world tested: rm→pull workflow validated with corrupted cache • Lock cleanup: 9 lock files properly cleaned during rm operations • Sanitized JSON: No cache paths or implementation details exposed Testing Status: Basic unit tests implemented, manual validation successful Note: Test suite requires update for JSON API Specification v0.1.1 Package: Installable as mlxk-json alongside 1.1.0 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
4.4 KiB
Python
117 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
"""MLX-Knife 2.0 CLI - JSON-first architecture."""
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from typing import Dict, Any
|
|
|
|
from . import __version__
|
|
from .operations.list import list_models
|
|
from .operations.health import health_check_operation
|
|
from .operations.pull import pull_operation
|
|
from .operations.rm import rm_operation
|
|
from .operations.show import show_model_operation
|
|
|
|
|
|
def format_json_output(data: Dict[str, Any]) -> str:
|
|
"""Format output as JSON."""
|
|
return json.dumps(data, indent=2)
|
|
|
|
|
|
def handle_error(error_type: str, message: str) -> Dict[str, Any]:
|
|
"""Format error as JSON response."""
|
|
return {
|
|
"status": "error",
|
|
"command": None,
|
|
"data": None,
|
|
"error": {
|
|
"type": error_type,
|
|
"message": message
|
|
}
|
|
}
|
|
|
|
|
|
def main():
|
|
"""Main CLI entry point."""
|
|
parser = argparse.ArgumentParser(
|
|
prog="mlxk2",
|
|
description="MLX-Knife 2.0 - JSON-first model management"
|
|
)
|
|
|
|
# Add version argument
|
|
parser.add_argument(
|
|
"--version",
|
|
action="version",
|
|
version=f"mlxk2 {__version__}"
|
|
)
|
|
|
|
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
|
|
# List command
|
|
list_parser = subparsers.add_parser("list", help="List all cached models")
|
|
list_parser.add_argument("pattern", nargs="?", help="Filter models by pattern (optional)")
|
|
list_parser.add_argument("--json", action="store_true", help="Output in JSON format (default in alpha)")
|
|
|
|
# Health command
|
|
health_parser = subparsers.add_parser("health", help="Check model health")
|
|
health_parser.add_argument("model", nargs="?", help="Model pattern to check (optional)")
|
|
health_parser.add_argument("--json", action="store_true", help="Output in JSON format (default in alpha)")
|
|
|
|
# Show command
|
|
show_parser = subparsers.add_parser("show", help="Show detailed model information")
|
|
show_parser.add_argument("model", help="Model name to show")
|
|
show_parser.add_argument("--files", action="store_true", help="Include file listing")
|
|
show_parser.add_argument("--config", action="store_true", help="Include config.json content")
|
|
show_parser.add_argument("--json", action="store_true", help="Output in JSON format (default in alpha)")
|
|
|
|
# Pull command
|
|
pull_parser = subparsers.add_parser("pull", help="Download a model")
|
|
pull_parser.add_argument("model", help="Model name to download")
|
|
pull_parser.add_argument("--json", action="store_true", help="Output in JSON format (default in alpha)")
|
|
|
|
# Remove command
|
|
rm_parser = subparsers.add_parser("rm", help="Delete a model")
|
|
rm_parser.add_argument("model", help="Model name to delete")
|
|
rm_parser.add_argument("-f", "--force", action="store_true", help="Delete without confirmation")
|
|
rm_parser.add_argument("--json", action="store_true", help="Output in JSON format (default in alpha)")
|
|
|
|
args = parser.parse_args()
|
|
|
|
try:
|
|
# In alpha version, --json flag is required for broke-cluster compatibility
|
|
if args.command and not hasattr(args, 'json'):
|
|
result = handle_error("CommandError", "Internal error: --json flag not found")
|
|
elif args.command and not args.json:
|
|
result = handle_error("JsonRequired", "MLX-Knife 2.0-alpha requires --json flag. Use: mlxk2 " + args.command + " --json")
|
|
elif args.command == "list":
|
|
result = list_models(pattern=args.pattern)
|
|
elif args.command == "health":
|
|
result = health_check_operation(args.model)
|
|
elif args.command == "show":
|
|
result = show_model_operation(args.model, args.files, args.config)
|
|
elif args.command == "pull":
|
|
result = pull_operation(args.model)
|
|
elif args.command == "rm":
|
|
result = rm_operation(args.model, args.force)
|
|
elif args.command is None:
|
|
result = handle_error("CommandError", "No command specified")
|
|
else:
|
|
result = handle_error("CommandError", f"Unknown command: {args.command}")
|
|
|
|
print(format_json_output(result))
|
|
|
|
# Exit with appropriate code
|
|
if result["status"] == "error":
|
|
sys.exit(1)
|
|
else:
|
|
sys.exit(0)
|
|
|
|
except Exception as e:
|
|
error_result = handle_error("InternalError", str(e))
|
|
print(format_json_output(error_result))
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |