Skip to content

Commit c8b84cd

Browse files
authored
Merge pull request #10 from M9nx/copilot/allow-model-selection-option
Add embedding profile size aliases (small/base/large)
2 parents 4a69ab5 + 135c659 commit c8b84cd

6 files changed

Lines changed: 56 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ codexa init
8888
```
8989

9090
CodexA auto-detects your available RAM and picks the best embedding model.
91-
Or choose a model profile explicitly:
91+
Or choose a model profile explicitly (aliases: small → fast, base → balanced, large → precise):
9292

9393
```bash
9494
codexa init --profile fast # mxbai-embed-xsmall — low RAM (<1 GB)

docs/guide/quickstart.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ codexa init --profile balanced # Default, ~2 GB RAM
2626
codexa init --profile precise # Best quality, ~4 GB RAM
2727
```
2828

29+
Aliases: `small``fast`, `base``balanced`, `large``precise`.
30+
2931
Compare models on your codebase: `codexa models benchmark`
3032
:::
3133

semantic_code_intelligence/cli/commands/init_cmd.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
save_config,
1414
)
1515
from semantic_code_intelligence.embeddings.model_registry import (
16+
CLI_PROFILE_CHOICES,
1617
recommend_profile_for_ram,
1718
resolve_profile,
1819
)
@@ -94,9 +95,12 @@ def _generate_vscode_mcp_config(root: Path) -> bool:
9495
@click.option(
9596
"--profile",
9697
"profile_name",
97-
type=click.Choice(["fast", "balanced", "precise"], case_sensitive=False),
98+
type=click.Choice(CLI_PROFILE_CHOICES, case_sensitive=False),
9899
default=None,
99-
help="Embedding model profile: fast (tiny, low RAM), balanced (default), precise (code-optimised).",
100+
help=(
101+
"Embedding model profile: fast (low RAM), balanced (default), or precise (code-optimized). "
102+
"Size aliases (small/base/large) and named aliases (default/quality/code) are supported."
103+
),
100104
)
101105
@click.pass_context
102106
def init_cmd(ctx: click.Context, path: str, auto_index: bool, setup_vscode: bool, profile_name: str | None) -> None:

semantic_code_intelligence/cli/commands/models_cmd.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from semantic_code_intelligence.config.settings import AppConfig, load_config, save_config
1111
from semantic_code_intelligence.embeddings.model_registry import (
1212
AVAILABLE_MODELS,
13+
CLI_PROFILE_CHOICES,
1314
DEFAULT_MODEL,
1415
MODEL_ALIASES,
1516
MODEL_PROFILES,
@@ -216,7 +217,23 @@ def models_profiles(json_mode: bool) -> None:
216217
console.print(table)
217218
if available_gb:
218219
print_info(f"Detected RAM: {available_gb:.1f} GB — recommended profile marked with ⭐")
219-
print_info("Use: codexa init --profile <fast|balanced|precise>")
220+
221+
canonical_names = sorted(MODEL_PROFILES.keys())
222+
print_info(f"Use: codexa init --profile <{'|'.join(canonical_names)}>")
223+
224+
alias_map: dict[str, set[str]] = {}
225+
for choice in CLI_PROFILE_CHOICES:
226+
profile = resolve_profile(choice)
227+
if profile is None or choice == profile.name:
228+
continue
229+
alias_map.setdefault(profile.name, set()).add(choice)
230+
231+
if alias_map:
232+
alias_parts = []
233+
for name in sorted(alias_map.keys()):
234+
aliases = "/".join(sorted(alias_map[name]))
235+
alias_parts.append(f"{name} ({aliases})")
236+
print_info(f"Aliases also supported: {', '.join(alias_parts)}")
220237

221238

222239
@models_cmd.command("benchmark")

semantic_code_intelligence/embeddings/model_registry.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,21 @@ class ModelProfile:
134134

135135
PROFILE_ALIASES: dict[str, str] = {
136136
"small": "fast",
137+
"base": "balanced",
137138
"default": "balanced",
138139
"quality": "precise",
139140
"code": "precise",
141+
"large": "precise",
140142
}
141143

144+
CORE_PROFILES: list[str] = ["fast", "balanced", "precise"]
145+
ALL_PROFILE_NAMES = set(PROFILE_ALIASES.keys()) | set(MODEL_PROFILES.keys())
146+
CLI_PROFILE_CHOICES: list[str] = [
147+
*CORE_PROFILES,
148+
# Aliases can overlap canonical names; set operations ensure each appears once in the final list
149+
*sorted(set(ALL_PROFILE_NAMES) - set(CORE_PROFILES)),
150+
]
151+
142152

143153
def resolve_profile(name: str) -> ModelProfile | None:
144154
"""Resolve a profile name or alias to a ModelProfile."""

semantic_code_intelligence/tests/test_cli.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from semantic_code_intelligence.cli.main import cli
1414
from semantic_code_intelligence.embeddings.generator import BYTES_PER_GB
15+
from semantic_code_intelligence.embeddings.model_registry import MODEL_PROFILES
1516

1617

1718
@pytest.fixture
@@ -72,6 +73,24 @@ def test_init_default_path(self, runner: CliRunner):
7273
assert result.exit_code == 0
7374
assert Path(td, ".codexa").is_dir()
7475

76+
def test_init_profile_aliases(self, runner: CliRunner, tmp_path: Path):
77+
cases = [
78+
("small", "fast"),
79+
("base", "balanced"),
80+
("large", "precise"),
81+
]
82+
83+
for alias, expected_profile in cases:
84+
proj = tmp_path / alias
85+
proj.mkdir()
86+
result = runner.invoke(cli, ["init", str(proj), "--profile", alias])
87+
assert result.exit_code == 0
88+
assert "Model profile" in result.output
89+
assert MODEL_PROFILES[expected_profile].label in result.output
90+
91+
cfg = load_config(proj)
92+
assert cfg.embedding.model_name == MODEL_PROFILES[expected_profile].model_name
93+
7594
def test_init_saves_recommended_batch_size(self, runner: CliRunner, tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
7695
# Force deterministic resource detection so recommendations are stable in tests
7796
monkeypatch.setattr(

0 commit comments

Comments
 (0)