Skip to content

Commit 1fefb15

Browse files
authored
Merge pull request #477 from cecli-dev/v0.98.2
V0.98.2
2 parents 05e9595 + 1896707 commit 1fefb15

14 files changed

Lines changed: 117 additions & 60 deletions

File tree

cecli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from packaging import version
22

3-
__version__ = "0.98.0.dev"
3+
__version__ = "0.98.2.dev"
44
safe_version = __version__
55

66
try:

cecli/coders/agent_coder.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class AgentCoder(Coder):
4343
def __init__(self, *args, **kwargs):
4444
self.recently_removed = {}
4545
self.tool_usage_history = []
46+
self.loaded_custom_tools = []
4647
self.tool_usage_retries = 20
4748
self.last_round_tools = []
4849
self.tool_call_vectors = []
@@ -90,6 +91,7 @@ def __init__(self, *args, **kwargs):
9091
self.agent_config = self._get_agent_config()
9192
self._setup_agent()
9293
ToolRegistry.build_registry(agent_config=self.agent_config)
94+
self.loaded_custom_tools = ToolRegistry.loaded_custom_tools
9395
super().__init__(*args, **kwargs)
9496

9597
def _setup_agent(self):
@@ -196,6 +198,9 @@ def _initialize_skills_manager(self, config):
196198

197199
def show_announcements(self):
198200
super().show_announcements()
201+
if self.loaded_custom_tools:
202+
self.io.tool_output(f"Loaded custom tools: {', '.join(self.loaded_custom_tools)}")
203+
199204
skills = self.skills_manager.find_skills()
200205
if skills:
201206
skills_list = []
@@ -295,21 +300,6 @@ async def _execute_local_tool_calls(self, tool_calls_list):
295300
tasks.append(result)
296301
else:
297302
tasks.append(asyncio.to_thread(lambda: result))
298-
elif self.mcp_tools:
299-
for server_name, server_tools in self.mcp_tools:
300-
if any(
301-
t.get("function", {}).get("name") == norm_tool_name
302-
for t in server_tools
303-
):
304-
server = self.mcp_manager.get_server(server_name)
305-
if server:
306-
for params in parsed_args_list:
307-
tasks.append(
308-
self._execute_mcp_tool(server, norm_tool_name, params)
309-
)
310-
break
311-
else:
312-
all_results_content.append(f"Error: Unknown tool name '{tool_name}'")
313303
else:
314304
all_results_content.append(f"Error: Unknown tool name '{tool_name}'")
315305
if tasks:

cecli/coders/base_coder.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ def __init__(
544544
max_code_line_length=map_max_line_length,
545545
repo_root=self.root,
546546
use_memory_cache=repomap_in_memory,
547-
use_enhanced_map=False if not self.args or self.args.use_enhanced_map else True,
547+
use_enhanced_map=getattr(self.args, "use_enhanced_map", False),
548548
)
549549

550550
self.summarizer = summarizer or ChatSummary(
@@ -3221,12 +3221,13 @@ async def show_send_output_stream(self, completion):
32213221
try:
32223222
func = chunk.choices[0].delta.function_call
32233223
# dump(func)
3224-
for k, v in func.items():
3225-
self.tool_reflection = True
3226-
self.io.update_spinner_suffix(v)
3224+
if func:
3225+
for k, v in func.items():
3226+
self.tool_reflection = True
3227+
self.io.update_spinner_suffix(v)
32273228

3228-
received_content = True
3229-
self.token_profiler.on_token()
3229+
received_content = True
3230+
self.token_profiler.on_token()
32303231
except AttributeError:
32313232
pass
32323233

cecli/helpers/plugin_manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ def normalize_filename(filename: str) -> str:
3737
:param filename: Original filename
3838
:return: Normalized module name
3939
"""
40+
if not filename:
41+
return ""
4042
# Remove extension
4143
name = Path(filename).stem
4244

@@ -58,6 +60,8 @@ def load_module(source, module_name=None, reload=False):
5860
:param module_name: name of module to register in sys.modules
5961
:return: loaded module
6062
"""
63+
if not source:
64+
return None
6165
# Convert to absolute path for cache key
6266
source_path = Path(source).resolve()
6367

cecli/helpers/requests.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def flush_user_messages():
125125
return result
126126

127127

128-
def add_continue_for_no_prefill(model, messages):
128+
def add_continue_for_no_prefill(model, messages, tools):
129129
"""Add a 'Continue' user message for models that don't support assistant prefill.
130130
131131
Args:
@@ -139,20 +139,34 @@ def add_continue_for_no_prefill(model, messages):
139139
# Check if model doesn't support assistant prefill
140140
# If not, inject a dummy user message with content "Continue"
141141
# but only if the last message is not already a user message
142+
append_message = False
143+
142144
if not model.info.get("supports_assistant_prefill", False):
143145
# Only add "Continue" if the last message is not a user message
144146
if not messages or messages[-1].get("role") != "user":
145147
# Add a user message with content "Continue" to the messages list
146-
messages.append({"role": "user", "content": "Continue"})
148+
append_message = True
149+
150+
if (
151+
tools
152+
and messages
153+
and messages[-1].get("role") == "assistant"
154+
and messages[-1].get("prefix", False)
155+
):
156+
messages[-1].pop("prefix", None)
157+
append_message = True
158+
159+
if append_message:
160+
messages.append({"role": "user", "content": "Continue"})
147161

148162
return messages
149163

150164

151-
def model_request_parser(model, messages):
165+
def model_request_parser(model, messages, tools):
152166
messages = thought_signature(model, messages)
153167
messages = remove_empty_tool_calls(messages)
154168
messages = concatenate_user_messages(messages)
155169
messages = ensure_alternating_roles(messages)
156170
messages = add_reasoning_content(messages)
157-
messages = add_continue_for_no_prefill(model, messages)
171+
messages = add_continue_for_no_prefill(model, messages, tools)
158172
return messages

cecli/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ async def send_completion(
977977
):
978978
if os.environ.get("CECLI_SANITY_CHECK_TURNS"):
979979
sanity_check_messages(messages)
980-
messages = model_request_parser(self, messages)
980+
messages = model_request_parser(self, messages, tools)
981981
if self.verbose:
982982
for message in messages:
983983
msg_role = message.get("role")
@@ -1120,7 +1120,7 @@ async def simple_send_with_retries(self, messages, max_tokens=None):
11201120
from cecli.exceptions import LiteLLMExceptions
11211121

11221122
litellm_ex = LiteLLMExceptions()
1123-
messages = model_request_parser(self, messages)
1123+
messages = model_request_parser(self, messages, None)
11241124
retry_delay = 0.125
11251125
if self.verbose:
11261126
dump(messages)

cecli/tools/finished.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
class Tool(BaseTool):
55
NORM_NAME = "finished"
6+
TRACK_INVOCATIONS = False
67
SCHEMA = {
78
"type": "function",
89
"function": {

cecli/tools/show_context.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,7 @@ def execute(cls, coder, show, **kwargs):
277277
except Exception as e:
278278
# Handle unexpected errors during processing
279279
return handle_tool_error(coder, tool_name, e)
280+
281+
@classmethod
282+
def on_duplicate_request(cls, coder, **kwargs):
283+
coder.edit_allowed = True

cecli/tools/update_todo_list.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ def execute(cls, coder, tasks, append=False, change_id=None, dry_run=False, **kw
7676
remaining_tasks = []
7777

7878
for task_item in tasks:
79+
if not isinstance(task_item, dict):
80+
task_item = {
81+
"task": str(task_item),
82+
"done": False,
83+
"current": False,
84+
}
85+
7986
if task_item.get("done", False):
8087
done_tasks.append(f"✓ {task_item['task']}")
8188
else:
@@ -197,6 +204,13 @@ def format_output(cls, coder, mcp_server, tool_response):
197204
remaining_tasks = []
198205

199206
for task_item in tasks:
207+
if not isinstance(task_item, dict):
208+
task_item = {
209+
"task": str(task_item),
210+
"done": False,
211+
"current": False,
212+
}
213+
200214
if task_item.get("done", False):
201215
done_tasks.append(f"✓ {task_item['task']}")
202216
else:

cecli/tools/utils/base_tool.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def process_response(cls, coder, params):
8181
f"Tool '{tool_name}' has been called with identical parameters recently. "
8282
"This request is denied to prevent repeated operations."
8383
)
84+
cls.on_duplicate_request(coder, **params)
8485
return handle_tool_error(coder, tool_name, ValueError(error_msg))
8586

8687
# Add current invocation to history (keeping only last 3)
@@ -99,3 +100,7 @@ def process_response(cls, coder, params):
99100
@classmethod
100101
def format_output(cls, coder, mcp_server, tool_response):
101102
print_tool_response(coder=coder, mcp_server=mcp_server, tool_response=tool_response)
103+
104+
@classmethod
105+
def on_duplicate_request(cls, coder, **kwargs):
106+
pass

0 commit comments

Comments
 (0)