Commit a3c476ec authored by Your Name's avatar Your Name

Add --alias support for model names

- CLI (coder): Add --alias argument to create model aliases
- Config: Add model_aliases dict and resolve_model() method
- Server (coderai): Add server-side alias support with --model-alias
- Aliases are resolved in both client and server when making API calls
- Aliases appear in /v1/models endpoint
- Aliases are persisted in config file
parent aafd41eb
......@@ -149,6 +149,7 @@ class Config:
token: Optional[str] = None
system_prompt: str = DEFAULT_SYSTEM_PROMPT
model: str = "default"
model_aliases: Dict[str, str] = None # Alias -> Model mapping
small: bool = False # Use small model optimizations
tiny: bool = False # Use tiny model optimizations (minimal)
micro: bool = False # Use micro model optimizations (ultra-minimal)
......@@ -163,6 +164,12 @@ class Config:
def __post_init__(self):
if self.confirm_commands is None:
self.confirm_commands = {}
if self.model_aliases is None:
self.model_aliases = {}
def resolve_model(self, model: str) -> str:
"""Resolve model alias to actual model name."""
return self.model_aliases.get(model, model)
@classmethod
def load(cls, config_path: Optional[str] = None) -> "Config":
......@@ -180,6 +187,7 @@ class Config:
config.token = data.get('token')
config.system_prompt = data.get('system_prompt', config.system_prompt)
config.model = data.get('model', config.model)
config.model_aliases = data.get('model_aliases', config.model_aliases)
config.small = data.get('small', config.small)
config.tiny = data.get('tiny', config.tiny)
config.micro = data.get('micro', config.micro)
......@@ -206,6 +214,7 @@ class Config:
'token': self.token,
'system_prompt': self.system_prompt,
'model': self.model,
'model_aliases': self.model_aliases,
'small': self.small,
'tiny': self.tiny,
'micro': self.micro,
......@@ -556,7 +565,7 @@ class CoderClient:
# Build payload, conditionally including tools
payload = {
"model": self.config.model,
"model": self.config.resolve_model(self.config.model),
"messages": messages,
"stream": stream
}
......@@ -1040,7 +1049,7 @@ class CoderClient:
# Build payload, conditionally including tools
payload = {
"model": self.config.model,
"model": self.config.resolve_model(self.config.model),
"messages": messages,
"stream": True
}
......@@ -1372,6 +1381,11 @@ Examples:
help='Model name to use (default: "default", temporary override)'
)
parser.add_argument(
'--alias',
help='Create an alias for the model (alias -> model mapping)'
)
parser.add_argument(
'--config',
help='Path to config file (default: ~/.config/coderai/cli.json)'
......@@ -1459,6 +1473,7 @@ Examples:
'token': config.token,
'system_prompt': config.system_prompt,
'model': config.model,
'model_aliases': config.model_aliases,
'small': config.small,
'tiny': config.tiny,
'max_context': config.max_context,
......@@ -1478,6 +1493,12 @@ Examples:
config.token = args.token
if args.model:
config.model = args.model
if args.alias:
# Register alias: alias -> model mapping
# If model not specified, alias points to "default"
target_model = args.model if args.model else config.model
config.model_aliases[args.alias] = target_model
print(f"[Alias registered: {args.alias} -> {target_model}]")
if args.small:
config.small = True
if args.tiny:
......
......@@ -1969,6 +1969,8 @@ class MultiModelManager:
# Load mode settings
self.load_mode: str = "ondemand" # "ondemand", "loadall", "loadswap"
self.active_in_vram: Optional[str] = None # Which model is currently in VRAM
# Model aliases: alias -> actual model name mapping
self.model_aliases: Dict[str, str] = {}
@property
def audio_model(self) -> Optional[str]:
......@@ -2006,6 +2008,10 @@ class MultiModelManager:
self.image_models.append(model_name)
self.config[f"image:{model_name}"] = config or {}
def set_model_alias(self, alias: str, model_name: str):
"""Register an alias for a model."""
self.model_aliases[alias] = model_name
def get_model_for_request(self, requested_model: str) -> Optional[ModelManager]:
"""
Get the appropriate model manager for a request based on model name.
......@@ -2018,8 +2024,13 @@ class MultiModelManager:
- "vision:modelname" or "image:modelname" -> use specific image model
- "tts" -> use TTS model
- "tts:modelname" -> use specific TTS model
- Custom aliases -> resolve to actual model name
- Otherwise match by model ID in multi_model_manager.models
"""
# Resolve custom aliases first
if requested_model in self.model_aliases:
requested_model = self.model_aliases[requested_model]
# Handle empty or "default" model names
if not requested_model or requested_model == "default":
if self.default_model and self.default_model in self.models:
......@@ -2175,6 +2186,10 @@ class MultiModelManager:
continue
models.append(ModelInfo(id=key))
# Add custom model aliases
for alias in self.model_aliases:
models.append(ModelInfo(id=alias))
return models if models else [ModelInfo(id="default")]
def swap_model_to_vram(self, model_key: str) -> bool:
......@@ -3735,6 +3750,16 @@ def parse_args():
default=None,
help="Model name, path, or URL for text-to-text LLM. Can be specified multiple times for multiple models.",
)
parser.add_argument(
"--model-alias",
type=str,
action="append",
default=None,
dest="model_aliases",
nargs=2,
metavar=("ALIAS", "MODEL"),
help="Register an alias for a model. Format: --model-alias <alias_name> <actual_model>",
)
parser.add_argument(
"--backend",
type=str,
......@@ -4388,6 +4413,12 @@ def main():
if model_name is None and not audio_models and not args.tts_model:
print(f"Pre-loading image model...")
# Register model aliases if specified
if args.model_aliases:
print(f"\nRegistering model aliases:")
for alias, model in args.model_aliases:
multi_model_manager.set_model_alias(alias, model)
print(f" {alias} -> {model}")
# Start the server
import uvicorn
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment