Skip to content

Commit 2b7e9d3

Browse files
committed
#399: Add back /editor-model slash command
1 parent 48af3b9 commit 2b7e9d3

3 files changed

Lines changed: 134 additions & 8 deletions

File tree

cecli/commands/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
# Import and register commands
2525
from .drop import DropCommand
2626
from .editor import EditCommand, EditorCommand
27+
from .editor_model import EditorModelCommand
2728
from .exit import ExitCommand
2829
from .git import GitCommand
2930
from .help import HelpCommand
@@ -110,6 +111,7 @@
110111
CommandRegistry.register(AddCommand)
111112
CommandRegistry.register(ModelCommand)
112113
CommandRegistry.register(WeakModelCommand)
114+
CommandRegistry.register(EditorModelCommand)
113115
CommandRegistry.register(WebCommand)
114116
CommandRegistry.register(LintCommand)
115117
CommandRegistry.register(TestCommand)
@@ -175,6 +177,7 @@
175177
"AddCommand",
176178
"ModelCommand",
177179
"WeakModelCommand",
180+
"EditorModelCommand",
178181
"WebCommand",
179182
"LintCommand",
180183
"TestCommand",

cecli/commands/editor_model.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
from typing import List
2+
3+
import cecli.models as models
4+
from cecli.commands.utils.base_command import BaseCommand
5+
from cecli.commands.utils.helpers import format_command_result
6+
7+
8+
class EditorModelCommand(BaseCommand):
9+
NORM_NAME = "editor-model"
10+
DESCRIPTION = "Switch the Editor Model to a new LLM"
11+
12+
@classmethod
13+
async def execute(cls, io, coder, args, **kwargs):
14+
"""Execute the editor-model command with given parameters."""
15+
arg_split = args.split(" ", 1)
16+
model_name = arg_split[0].strip()
17+
if not model_name:
18+
# If no model name provided, show current editor model
19+
current_editor_model = coder.main_model.editor_model.name
20+
io.tool_output(f"Current editor model: {current_editor_model}")
21+
return format_command_result(
22+
io, "editor-model", f"Displayed current editor model: {current_editor_model}"
23+
)
24+
25+
# Create a new model with the same main model and editor model, but updated editor model
26+
model = models.Model(
27+
coder.main_model.name,
28+
editor_model=model_name,
29+
weak_model=coder.main_model.weak_model.name,
30+
io=io,
31+
)
32+
await models.sanity_check_models(io, model)
33+
34+
if len(arg_split) > 1:
35+
# implement architect coder-like generation call for editor model
36+
message = arg_split[1].strip()
37+
38+
# Store the original model configuration
39+
original_main_model = coder.main_model
40+
original_edit_format = coder.edit_format
41+
42+
# Create a temporary coder with the new model
43+
from cecli.coders import Coder
44+
45+
kwargs = dict()
46+
kwargs["main_model"] = model
47+
kwargs["edit_format"] = coder.edit_format # Keep the same edit format
48+
kwargs["suggest_shell_commands"] = False
49+
kwargs["total_cost"] = coder.total_cost
50+
kwargs["num_cache_warming_pings"] = 0
51+
kwargs["summarize_from_coder"] = False
52+
53+
new_kwargs = dict(io=io, from_coder=coder)
54+
new_kwargs.update(kwargs)
55+
56+
temp_coder = await Coder.create(**new_kwargs)
57+
temp_coder.cur_messages = []
58+
temp_coder.done_messages = []
59+
60+
verbose = kwargs.get("verbose", False)
61+
if verbose:
62+
temp_coder.show_announcements()
63+
64+
try:
65+
await temp_coder.generate(user_message=message, preproc=False)
66+
coder.move_back_cur_messages(
67+
f"Weak model {model_name} made those changes to the files."
68+
)
69+
coder.total_cost = temp_coder.total_cost
70+
coder.coder_commit_hashes = temp_coder.coder_commit_hashes
71+
72+
# Restore the original model configuration
73+
from cecli.commands import SwitchCoderSignal
74+
75+
raise SwitchCoderSignal(
76+
main_model=original_main_model, edit_format=original_edit_format
77+
)
78+
except Exception as e:
79+
# If there's an error, still restore the original model
80+
if not isinstance(e, SwitchCoderSignal):
81+
io.tool_error(str(e))
82+
raise SwitchCoderSignal(
83+
main_model=original_main_model, edit_format=original_edit_format
84+
)
85+
else:
86+
# Re-raise SwitchCoderSignal if that's what was thrown
87+
raise
88+
else:
89+
from cecli.commands import SwitchCoderSignal
90+
91+
raise SwitchCoderSignal(main_model=model, edit_format=coder.edit_format)
92+
93+
@classmethod
94+
def get_completions(cls, io, coder, args) -> List[str]:
95+
"""Get completion options for edit_model command."""
96+
return models.get_chat_model_names()
97+
98+
@classmethod
99+
def get_help(cls) -> str:
100+
"""Get help text for the edit_model command."""
101+
help_text = super().get_help()
102+
help_text += "\nUsage:\n"
103+
help_text += " /editor-model <model-name> # Switch to a new editor model\n"
104+
help_text += (
105+
" /editor-model <model-name> <prompt> # Use a specific editor model for a single"
106+
" prompt\n"
107+
)
108+
help_text += "\nExamples:\n"
109+
help_text += (
110+
" /editor-model gpt-4o-mini # Switch to GPT-4o Mini as editor model\n"
111+
)
112+
help_text += (
113+
" /editor-model claude-3-haiku # Switch to Claude 3 Haiku as editor model\n"
114+
)
115+
help_text += ' /editor-model o1-mini "review this code" # Use o1-mini to review code\n'
116+
help_text += (
117+
"\nWhen switching editor models, the main model and editor model remain unchanged.\n"
118+
)
119+
help_text += (
120+
"\nIf you provide a prompt after the model name, that editor model will be used\n"
121+
)
122+
help_text += "just for that prompt, then you'll return to your original editor model.\n"
123+
return help_text

cecli/commands/weak_model.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class WeakModelCommand(BaseCommand):
1111

1212
@classmethod
1313
async def execute(cls, io, coder, args, **kwargs):
14-
"""Execute the weak_model command with given parameters."""
14+
"""Execute the weak-model command with given parameters."""
1515
arg_split = args.split(" ", 1)
1616
model_name = arg_split[0].strip()
1717
if not model_name:
@@ -92,27 +92,27 @@ async def execute(cls, io, coder, args, **kwargs):
9292

9393
@classmethod
9494
def get_completions(cls, io, coder, args) -> List[str]:
95-
"""Get completion options for weak_model command."""
95+
"""Get completion options for weak-model command."""
9696
return models.get_chat_model_names()
9797

9898
@classmethod
9999
def get_help(cls) -> str:
100-
"""Get help text for the weak_model command."""
100+
"""Get help text for the weak-model command."""
101101
help_text = super().get_help()
102102
help_text += "\nUsage:\n"
103-
help_text += " /weak_model <model-name> # Switch to a new weak model\n"
103+
help_text += " /weak-model <model-name> # Switch to a new weak model\n"
104104
help_text += (
105-
" /weak_model <model-name> <prompt> # Use a specific weak model for a single"
105+
" /weak-model <model-name> <prompt> # Use a specific weak model for a single"
106106
" prompt\n"
107107
)
108108
help_text += "\nExamples:\n"
109109
help_text += (
110-
" /weak_model gpt-4o-mini # Switch to GPT-4o Mini as weak model\n"
110+
" /weak-model gpt-4o-mini # Switch to GPT-4o Mini as weak model\n"
111111
)
112112
help_text += (
113-
" /weak_model claude-3-haiku # Switch to Claude 3 Haiku as weak model\n"
113+
" /weak-model claude-3-haiku # Switch to Claude 3 Haiku as weak model\n"
114114
)
115-
help_text += ' /weak_model o1-mini "review this code" # Use o1-mini to review code\n'
115+
help_text += ' /weak-model o1-mini "review this code" # Use o1-mini to review code\n'
116116
help_text += (
117117
"\nWhen switching weak models, the main model and editor model remain unchanged.\n"
118118
)

0 commit comments

Comments
 (0)