Skip to content

Commit e7d1580

Browse files
authored
fix: solve problems with codegate cli and previous context (#757)
* fix: solve problems with codegate cli and previous context Cline was not properly detecting the codegate cli commands when there was some previous context * fix to allow subcommands * fix for copilot
1 parent 404768f commit e7d1580

File tree

3 files changed

+72
-21
lines changed

3 files changed

+72
-21
lines changed

src/codegate/pipeline/cli/cli.py

+46-20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
PipelineStep,
1111
)
1212
from codegate.pipeline.cli.commands import CustomInstructions, Version, Workspace
13+
from codegate.utils.utils import get_tool_name_from_messages
1314

1415
HELP_TEXT = """
1516
## CodeGate CLI\n
@@ -77,27 +78,52 @@ async def process(
7778

7879
if last_user_message is not None:
7980
last_user_message_str, _ = last_user_message
80-
cleaned_message_str = re.sub(r"<.*?>", "", last_user_message_str).strip()
81-
splitted_message = cleaned_message_str.lower().split(" ")
82-
# We expect codegate as the first word in the message
83-
if splitted_message[0] == "codegate":
84-
context.shortcut_response = True
85-
args = shlex.split(cleaned_message_str)
86-
cmd_out = await codegate_cli(args[1:])
87-
88-
if cleaned_message_str != last_user_message_str:
89-
# it came from Cline, need to wrap into tags
90-
cmd_out = (
91-
f"<attempt_completion><result>{cmd_out}</result></attempt_completion>\n"
92-
)
93-
return PipelineResult(
94-
response=PipelineResponse(
95-
step_name=self.name,
96-
content=cmd_out,
97-
model=request["model"],
98-
),
99-
context=context,
81+
last_user_message_str = last_user_message_str.strip()
82+
base_tool = get_tool_name_from_messages(request)
83+
codegate_regex = re.compile(r"^codegate(?:\s+(.*))?", re.IGNORECASE)
84+
85+
if base_tool and base_tool == "cline":
86+
# Check if there are <task> or <feedback> tags
87+
tag_match = re.search(
88+
r"<(task|feedback)>(.*?)</\1>", last_user_message_str, re.DOTALL
10089
)
90+
if tag_match:
91+
# Extract the content between the tags
92+
stripped_message = tag_match.group(2).strip()
93+
else:
94+
# If no <task> or <feedback> tags, use the entire message
95+
stripped_message = last_user_message_str.strip()
96+
97+
# Remove all other XML tags and trim whitespace
98+
stripped_message = re.sub(r"<[^>]+>", "", stripped_message).strip()
99+
100+
# Check if "codegate" is the first word
101+
match = codegate_regex.match(stripped_message)
102+
else:
103+
# Check if "codegate" is the first word in the message
104+
match = codegate_regex.match(last_user_message_str)
105+
if match:
106+
command = match.group(1) or ""
107+
command = command.strip()
108+
109+
# Process the command
110+
args = shlex.split(f"codegate {command}")
111+
if args:
112+
context.shortcut_response = True
113+
cmd_out = await codegate_cli(args[1:])
114+
if base_tool and base_tool == "cline":
115+
cmd_out = (
116+
f"<attempt_completion><result>{cmd_out}</result></attempt_completion>\n"
117+
)
118+
119+
return PipelineResult(
120+
response=PipelineResponse(
121+
step_name=self.name,
122+
content=cmd_out,
123+
model=request["model"],
124+
),
125+
context=context,
126+
)
101127

102128
# Fall through
103129
return PipelineResult(request=request, context=context)

src/codegate/providers/copilot/provider.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,15 @@ async def _forward_data_through_pipeline(self, data: bytes) -> Union[HttpRequest
291291
# we couldn't parse this into an HTTP request, so we just pass through
292292
return data
293293

294-
body, context = await self._body_through_pipeline(
294+
result = await self._body_through_pipeline(
295295
http_request.method,
296296
http_request.path,
297297
http_request.headers,
298298
http_request.body,
299299
)
300+
if not result:
301+
return data
302+
body, context = result
300303
# TODO: it's weird that we're overwriting the context.
301304
# Should we set the context once? Maybe when
302305
# creating the pipeline instance?

src/codegate/utils/utils.py

+22
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,25 @@ def generate_vector_string(package) -> str:
2929
# add description
3030
vector_str += f" - Package offers this functionality: {package['description']}"
3131
return vector_str
32+
33+
34+
def get_tool_name_from_messages(data):
35+
"""
36+
Identifies the tool name based on the content of the messages.
37+
38+
Args:
39+
request (dict): The request object containing messages.
40+
tools (list): A list of tool names to search for.
41+
42+
Returns:
43+
str: The name of the tool found in the messages, or None if no match is found.
44+
"""
45+
tools = [
46+
"Cline",
47+
]
48+
for message in data.get("messages", []):
49+
message_content = str(message.get("content", ""))
50+
for tool in tools:
51+
if tool in message_content:
52+
return tool.lower()
53+
return None

0 commit comments

Comments
 (0)