Skip to content

Commit 05e9595

Browse files
authored
Merge pull request #475 from cecli-dev/v0.98.1
V0.98.1
2 parents d2b55a0 + b0893bf commit 05e9595

File tree

20 files changed

+626
-325
lines changed

20 files changed

+626
-325
lines changed

cecli/coders/agent_coder.py

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from cecli import utils
1515
from cecli.change_tracker import ChangeTracker
16-
from cecli.helpers import nested
16+
from cecli.helpers import nested, responses
1717
from cecli.helpers.background_commands import BackgroundCommandManager
1818
from cecli.helpers.conversation import ConversationService, MessageTag
1919
from cecli.helpers.similarity import (
@@ -124,7 +124,7 @@ def _get_agent_config(self):
124124
config["command_timeout"] = nested.getter(config, "command_timeout", 30)
125125
config["hot_reload"] = nested.getter(config, "hot_reload", False)
126126

127-
config["tools_paths"] = nested.getter(config, "tools_paths", [])
127+
config["tools_paths"] = nested.getter(config, ["tools_paths", "tool_paths"], [])
128128
config["tools_includelist"] = nested.getter(
129129
config, ["tools_includelist", "tools_whitelist"], []
130130
)
@@ -246,7 +246,7 @@ async def _execute_local_tool_calls(self, tool_calls_list):
246246
tool_name = tool_call.function.name
247247
result_message = ""
248248
try:
249-
if tool_name.lower() in self.write_tools:
249+
if responses.unprefix_tool_name(tool_name)[1].lower() in self.write_tools:
250250
used_write_tool = True
251251

252252
args_string = tool_call.function.arguments.strip()
@@ -738,8 +738,11 @@ async def process_tool_calls(self, tool_call_response):
738738

739739
if tool_name:
740740
self.last_round_tools.append(tool_name)
741+
content = (
742+
str(self.partial_response_content) if self.partial_response_content else ""
743+
)
741744
tool_call_str = str(tool_call_copy)
742-
tool_vector = create_bigram_vector((tool_call_str,))
745+
tool_vector = create_bigram_vector((tool_call_str, content))
743746
tool_vector_norm = normalize_vector(tool_vector)
744747
self.tool_call_vectors.append(tool_vector_norm)
745748
if self.last_round_tools:
@@ -753,6 +756,27 @@ async def process_tool_calls(self, tool_call_response):
753756
# Ensure we call base implementation to trigger execution of all tools (native + extracted)
754757
return await super().process_tool_calls(tool_call_response)
755758

759+
async def _execute_local_tools(self, tool_calls):
760+
"""Execute local tools via ToolRegistry."""
761+
return await self._execute_local_tool_calls(tool_calls)
762+
763+
async def _execute_mcp_tools(self, server, tool_calls):
764+
"""Execute MCP tools via LiteLLM."""
765+
responses = []
766+
for tool_call in tool_calls:
767+
# Use existing _execute_mcp_tool logic
768+
result = await self._execute_mcp_tool(
769+
server, tool_call.function.name, json.loads(tool_call.function.arguments)
770+
)
771+
responses.append(
772+
{
773+
"role": "tool",
774+
"tool_call_id": tool_call.id,
775+
"content": result,
776+
}
777+
)
778+
return responses
779+
756780
def get_active_model(self):
757781
if self.main_model.agent_model:
758782
return self.main_model.agent_model
@@ -870,14 +894,15 @@ def _get_repetitive_tools(self):
870894
Identifies repetitive tool usage patterns from rounds of tool calls.
871895
"""
872896
history_len = len(self.tool_usage_history)
873-
if history_len < 5:
897+
if history_len < 1:
874898
return set()
875899

876900
similarity_repetitive_tools = self._get_repetitive_tools_by_similarity()
877901

878902
if self.last_round_tools:
879903
last_round_has_write = any(
880-
tool.lower() in self.write_tools for tool in self.last_round_tools
904+
responses.unprefix_tool_name(tool)[1].lower() in self.write_tools
905+
for tool in self.last_round_tools
881906
)
882907
if last_round_has_write:
883908
# Remove half of the history when a write tool is used
@@ -889,7 +914,8 @@ def _get_repetitive_tools(self):
889914
return {
890915
tool
891916
for tool in similarity_repetitive_tools
892-
if tool.lower() in self.read_tools or tool.lower() in self.write_tools
917+
if responses.unprefix_tool_name(tool)[1].lower() in self.read_tools
918+
or responses.unprefix_tool_name(tool)[1].lower() in self.write_tools
893919
}
894920

895921
def _get_repetitive_tools_by_similarity(self):
@@ -990,6 +1016,8 @@ def _generate_tool_context(self, repetitive_tools):
9901016
)
9911017

9921018
context_parts.append("\n\n")
1019+
repetition_warning = None
1020+
9931021
if repetitive_tools:
9941022
if not self.model_kwargs:
9951023
self.model_kwargs = {
@@ -1019,7 +1047,7 @@ def _generate_tool_context(self, repetitive_tools):
10191047
)
10201048
self.model_kwargs["frequency_penalty"] = min(0, max(freq_penalty - 0.15, 0))
10211049

1022-
self.model_kwargs["temperature"] = min(self.model_kwargs["temperature"], 1)
1050+
self.model_kwargs["temperature"] = max(0, min(self.model_kwargs["temperature"], 1))
10231051
# One twentieth of the time, just straight reset the randomness
10241052
if random.random() < 0.05:
10251053
self.model_kwargs = {}
@@ -1028,11 +1056,11 @@ def _generate_tool_context(self, repetitive_tools):
10281056
self._last_repetitive_warning_turn = self.turn_count
10291057
self._last_repetitive_warning_severity += 1
10301058

1031-
repetition_warning = f"""
1032-
## Repetition Detected
1033-
You have been using the following tools repetitively: {', '.join([f'`{t}`' for t in repetitive_tools])}.
1034-
Do not repeat the same parameters for these tools in your next turns. Prioritize editing.
1035-
"""
1059+
repetition_warning = (
1060+
"## Repetition Detected\nYou have used the following tools repetitively:"
1061+
f" {', '.join([f'`{t}`' for t in repetitive_tools])}.\nDo not repeat the same"
1062+
" parameters for these tools in your next turns. Prioritize editing.\n"
1063+
)
10361064

10371065
if self._last_repetitive_warning_severity > 5:
10381066
self._last_repetitive_warning_severity = 0
@@ -1079,28 +1107,42 @@ def _generate_tool_context(self, repetitive_tools):
10791107
]
10801108
)
10811109

1082-
repetition_warning += f"""
1083-
## CRITICAL: Execution Loop Detected
1084-
You may be stuck in a cycle. To break the exploration loop and continue making progress, please do the following:
1085-
1. **Analyze**: Summarize your findings. Describe how you can stop repeating yourself and make progress.
1086-
2. **Reframe**: To help with creativity, include a 2-sentence story about {animal} {verb} {fruit} in your thoughts.
1087-
3. **Pivot**: Modify your current exploration strategy. Try alternative methods. Prioritize editing.
1088-
"""
1110+
repetition_warning += (
1111+
"## CRITICAL: Execution Loop Detected\nYou may be stuck in a cycle. To break"
1112+
" the exploration loop and continue making progress, please do the"
1113+
" following:\n1. **Analyze**: Summarize your findings. Describe how you can"
1114+
" stop repeating yourself and make progress.2. **Reframe**: To help with"
1115+
f" creativity, include a 2-sentence story about {animal} {verb} {fruit} in your"
1116+
" thoughts.\n3. **Pivot**: Modify your current exploration strategy. Try"
1117+
" alternative methods. Prioritize editing.\n"
1118+
)
10891119

1090-
context_parts.append(repetition_warning)
1120+
# context_parts.append(repetition_warning)
10911121
else:
10921122
self.model_kwargs = {}
10931123
self._last_repetitive_warning_severity = min(
10941124
self._last_repetitive_warning_severity - 1, 0
10951125
)
10961126

1127+
if repetition_warning:
1128+
ConversationService.get_manager(self).add_message(
1129+
message_dict=dict(role="user", content=repetition_warning),
1130+
tag=MessageTag.CUR,
1131+
hash_key=("repetition", "agent"),
1132+
mark_for_delete=0,
1133+
promotion=ConversationService.get_manager(self).DEFAULT_TAG_PROMOTION_VALUE + 2,
1134+
mark_for_demotion=1,
1135+
force=True,
1136+
)
1137+
10971138
context_parts.append("</context>")
10981139
return "\n".join(context_parts)
10991140

11001141
def _generate_write_context(self):
11011142
if self.last_round_tools:
11021143
last_round_has_write = any(
1103-
tool.lower() in self.write_tools for tool in self.last_round_tools
1144+
responses.unprefix_tool_name(tool)[1].lower() in self.write_tools
1145+
for tool in self.last_round_tools
11041146
)
11051147
if last_round_has_write:
11061148
context_parts = [

0 commit comments

Comments
 (0)