Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cecli/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# Import and register commands
from .drop import DropCommand
from .editor import EditCommand, EditorCommand
from .editor_model import EditorModelCommand
from .exit import ExitCommand
from .git import GitCommand
from .help import HelpCommand
Expand Down Expand Up @@ -110,6 +111,7 @@
CommandRegistry.register(AddCommand)
CommandRegistry.register(ModelCommand)
CommandRegistry.register(WeakModelCommand)
CommandRegistry.register(EditorModelCommand)
CommandRegistry.register(WebCommand)
CommandRegistry.register(LintCommand)
CommandRegistry.register(TestCommand)
Expand Down Expand Up @@ -175,6 +177,7 @@
"AddCommand",
"ModelCommand",
"WeakModelCommand",
"EditorModelCommand",
"WebCommand",
"LintCommand",
"TestCommand",
Expand Down
123 changes: 123 additions & 0 deletions cecli/commands/editor_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
from typing import List

import cecli.models as models
from cecli.commands.utils.base_command import BaseCommand
from cecli.commands.utils.helpers import format_command_result


class EditorModelCommand(BaseCommand):
NORM_NAME = "editor-model"
DESCRIPTION = "Switch the Editor Model to a new LLM"

@classmethod
async def execute(cls, io, coder, args, **kwargs):
"""Execute the editor-model command with given parameters."""
arg_split = args.split(" ", 1)
model_name = arg_split[0].strip()
if not model_name:
# If no model name provided, show current editor model
current_editor_model = coder.main_model.editor_model.name
io.tool_output(f"Current editor model: {current_editor_model}")
return format_command_result(
io, "editor-model", f"Displayed current editor model: {current_editor_model}"
)

# Create a new model with the same main model and editor model, but updated editor model
model = models.Model(
coder.main_model.name,
editor_model=model_name,
weak_model=coder.main_model.weak_model.name,
io=io,
)
await models.sanity_check_models(io, model)

if len(arg_split) > 1:
# implement architect coder-like generation call for editor model
message = arg_split[1].strip()

# Store the original model configuration
original_main_model = coder.main_model
original_edit_format = coder.edit_format

# Create a temporary coder with the new model
from cecli.coders import Coder

kwargs = dict()
kwargs["main_model"] = model
kwargs["edit_format"] = coder.edit_format # Keep the same edit format
kwargs["suggest_shell_commands"] = False
kwargs["total_cost"] = coder.total_cost
kwargs["num_cache_warming_pings"] = 0
kwargs["summarize_from_coder"] = False

new_kwargs = dict(io=io, from_coder=coder)
new_kwargs.update(kwargs)

temp_coder = await Coder.create(**new_kwargs)
temp_coder.cur_messages = []
temp_coder.done_messages = []

verbose = kwargs.get("verbose", False)
if verbose:
temp_coder.show_announcements()

try:
await temp_coder.generate(user_message=message, preproc=False)
coder.move_back_cur_messages(
f"Weak model {model_name} made those changes to the files."
)
coder.total_cost = temp_coder.total_cost
coder.coder_commit_hashes = temp_coder.coder_commit_hashes

# Restore the original model configuration
from cecli.commands import SwitchCoderSignal

raise SwitchCoderSignal(
main_model=original_main_model, edit_format=original_edit_format
)
except Exception as e:
# If there's an error, still restore the original model
if not isinstance(e, SwitchCoderSignal):
io.tool_error(str(e))
raise SwitchCoderSignal(
main_model=original_main_model, edit_format=original_edit_format
)
else:
# Re-raise SwitchCoderSignal if that's what was thrown
raise
else:
from cecli.commands import SwitchCoderSignal

raise SwitchCoderSignal(main_model=model, edit_format=coder.edit_format)

@classmethod
def get_completions(cls, io, coder, args) -> List[str]:
"""Get completion options for edit_model command."""
return models.get_chat_model_names()

@classmethod
def get_help(cls) -> str:
"""Get help text for the edit_model command."""
help_text = super().get_help()
help_text += "\nUsage:\n"
help_text += " /editor-model <model-name> # Switch to a new editor model\n"
help_text += (
" /editor-model <model-name> <prompt> # Use a specific editor model for a single"
" prompt\n"
)
help_text += "\nExamples:\n"
help_text += (
" /editor-model gpt-4o-mini # Switch to GPT-4o Mini as editor model\n"
)
help_text += (
" /editor-model claude-3-haiku # Switch to Claude 3 Haiku as editor model\n"
)
help_text += ' /editor-model o1-mini "review this code" # Use o1-mini to review code\n'
help_text += (
"\nWhen switching editor models, the main model and editor model remain unchanged.\n"
)
help_text += (
"\nIf you provide a prompt after the model name, that editor model will be used\n"
)
help_text += "just for that prompt, then you'll return to your original editor model.\n"
return help_text
16 changes: 8 additions & 8 deletions cecli/commands/weak_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class WeakModelCommand(BaseCommand):

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

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

@classmethod
def get_help(cls) -> str:
"""Get help text for the weak_model command."""
"""Get help text for the weak-model command."""
help_text = super().get_help()
help_text += "\nUsage:\n"
help_text += " /weak_model <model-name> # Switch to a new weak model\n"
help_text += " /weak-model <model-name> # Switch to a new weak model\n"
help_text += (
" /weak_model <model-name> <prompt> # Use a specific weak model for a single"
" /weak-model <model-name> <prompt> # Use a specific weak model for a single"
" prompt\n"
)
help_text += "\nExamples:\n"
help_text += (
" /weak_model gpt-4o-mini # Switch to GPT-4o Mini as weak model\n"
" /weak-model gpt-4o-mini # Switch to GPT-4o Mini as weak model\n"
)
help_text += (
" /weak_model claude-3-haiku # Switch to Claude 3 Haiku as weak model\n"
" /weak-model claude-3-haiku # Switch to Claude 3 Haiku as weak model\n"
)
help_text += ' /weak_model o1-mini "review this code" # Use o1-mini to review code\n'
help_text += ' /weak-model o1-mini "review this code" # Use o1-mini to review code\n'
help_text += (
"\nWhen switching weak models, the main model and editor model remain unchanged.\n"
)
Expand Down
Loading