From 7b1fbbe2beac5be59af78818e053e7bdb6f42e8e Mon Sep 17 00:00:00 2001
From: TIANYOU CHEN <42710806+CTY-git@users.noreply.github.com>
Date: Wed, 16 Apr 2025 12:21:47 +0800
Subject: [PATCH 1/4] add git tool

---
 patchwork/common/tools/git_tool.py         | 44 ++++++++++++++++++++++
 patchwork/common/tools/github_tool.py      |  2 +-
 patchwork/steps/GitHubAgent/GitHubAgent.py |  6 ++-
 3 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 patchwork/common/tools/git_tool.py

diff --git a/patchwork/common/tools/git_tool.py b/patchwork/common/tools/git_tool.py
new file mode 100644
index 000000000..4b32765aa
--- /dev/null
+++ b/patchwork/common/tools/git_tool.py
@@ -0,0 +1,44 @@
+from __future__ import annotations
+
+import os
+import subprocess
+
+from patchwork.common.tools.tool import Tool
+
+
+class GitTool(Tool, tool_name="git_tool",  abc_register=False):
+    def __init__(self, path: str):
+        super().__init__()
+        self.path = path
+
+    @property
+    def json_schema(self) -> dict:
+        return {
+            "name": "git_tool",
+            "description": """\
+Access to the Git CLI, the command is also `git` all args provided are used as is
+""",
+            "input_schema": {
+                "type": "object",
+                "properties": {
+                    "args": {
+                        "type": "array",
+                        "items": {"type": "string"},
+                        "description": "The args to run `git` command with.",
+                    }
+                },
+                "required": ["args"],
+            },
+        }
+
+    def execute(self, args: list[str]) -> str:
+        env = os.environ.copy()
+        p = subprocess.run(
+            ["gh", *args],
+            env=env,
+            cwd=self.path,
+            text=True,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT,
+        )
+        return p.stdout
diff --git a/patchwork/common/tools/github_tool.py b/patchwork/common/tools/github_tool.py
index aa5d5effe..16e418c08 100644
--- a/patchwork/common/tools/github_tool.py
+++ b/patchwork/common/tools/github_tool.py
@@ -6,7 +6,7 @@
 from patchwork.common.tools.tool import Tool
 
 
-class GitHubTool(Tool, tool_name="github_tool"):
+class GitHubTool(Tool, tool_name="github_tool",  abc_register=False):
     def __init__(self, path: str, gh_token: str):
         super().__init__()
         self.path = path
diff --git a/patchwork/steps/GitHubAgent/GitHubAgent.py b/patchwork/steps/GitHubAgent/GitHubAgent.py
index bc8d319c1..0ac014538 100644
--- a/patchwork/steps/GitHubAgent/GitHubAgent.py
+++ b/patchwork/steps/GitHubAgent/GitHubAgent.py
@@ -5,6 +5,7 @@
     AgentConfig,
     AgenticStrategyV2,
 )
+from patchwork.common.tools.git_tool import GitTool
 from patchwork.common.tools.github_tool import GitHubTool
 from patchwork.common.utils.utils import mustache_render
 from patchwork.step import Step
@@ -34,7 +35,10 @@ def __init__(self, inputs):
                 AgentConfig(
                     name="Assistant",
                     model="gemini-2.0-flash",
-                    tool_set=dict(github_tool=GitHubTool(base_path, inputs["github_api_key"])),
+                    tool_set=dict(
+                        github_tool=GitHubTool(base_path, inputs["github_api_key"]),
+                        git_tool=GitTool(base_path),
+                    ),
                     system_prompt="""\
 You are a senior software developer helping the program manager to obtain some data from GitHub.
 You can access github through the `gh` CLI app.

From 5bafb638391958f89f114d7d0a7973200d30a9d4 Mon Sep 17 00:00:00 2001
From: TIANYOU CHEN <42710806+CTY-git@users.noreply.github.com>
Date: Wed, 16 Apr 2025 12:25:11 +0800
Subject: [PATCH 2/4] bump version

---
 pyproject.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pyproject.toml b/pyproject.toml
index ab89dee54..d136584c5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "patchwork-cli"
-version = "0.0.123"
+version = "0.0.124"
 description = ""
 authors = ["patched.codes"]
 license = "AGPL"

From c953072cb18039a0d17b007a95f14aafc65414e4 Mon Sep 17 00:00:00 2001
From: TIANYOU CHEN <42710806+CTY-git@users.noreply.github.com>
Date: Wed, 16 Apr 2025 13:33:43 +0800
Subject: [PATCH 3/4] fixes

---
 patchwork/common/tools/git_tool.py | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/patchwork/common/tools/git_tool.py b/patchwork/common/tools/git_tool.py
index 4b32765aa..d5acbfa05 100644
--- a/patchwork/common/tools/git_tool.py
+++ b/patchwork/common/tools/git_tool.py
@@ -16,7 +16,7 @@ def json_schema(self) -> dict:
         return {
             "name": "git_tool",
             "description": """\
-Access to the Git CLI, the command is also `git` all args provided are used as is
+Access to the Git CLI, the command is also `git` all args provided are used as is.
 """,
             "input_schema": {
                 "type": "object",
@@ -24,7 +24,12 @@ def json_schema(self) -> dict:
                     "args": {
                         "type": "array",
                         "items": {"type": "string"},
-                        "description": "The args to run `git` command with.",
+                        "description": """
+The args to run `git` command with. 
+E.g. 
+[\"commit\", \"-m\", \"A commit message\"] to commit changes with a commit message.
+[\"add\", \".\"] to stage all changed files.
+""",
                     }
                 },
                 "required": ["args"],
@@ -34,7 +39,7 @@ def json_schema(self) -> dict:
     def execute(self, args: list[str]) -> str:
         env = os.environ.copy()
         p = subprocess.run(
-            ["gh", *args],
+            ["git", *args],
             env=env,
             cwd=self.path,
             text=True,

From af079bdcbd5103a101e9fc2a32f699edad062561 Mon Sep 17 00:00:00 2001
From: "patched.codes[bot]"
 <298395+patched.codes[bot]@users.noreply.github.com>
Date: Wed, 16 Apr 2025 05:42:26 +0000
Subject: [PATCH 4/4] Patched tests/cicd/generate_docstring/usage_example.py

---
 .../cicd/generate_docstring/usage_example.py  | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 tests/cicd/generate_docstring/usage_example.py

diff --git a/tests/cicd/generate_docstring/usage_example.py b/tests/cicd/generate_docstring/usage_example.py
new file mode 100644
index 000000000..29c9599b2
--- /dev/null
+++ b/tests/cicd/generate_docstring/usage_example.py
@@ -0,0 +1,30 @@
+import java.util.function.Function;
+
+public class Main {
+    public static void main(String[] args) {
+        // Example usage of a_plus_b with integers
+        System.out.println("Sum of 5 and 3: " + Test.a_plus_b(5, 3));
+
+        // Example usage of a_plus_b with keymap functionality
+        Function<Object, Comparable> lengthKeyMap = obj -> ((String)obj).length();
+        String str1 = "apple";
+        String str2 = "banana";
+        System.out.println("Comparison of 'apple' and 'banana': " + Test.a_plus_b(lengthKeyMap, str1, str2));
+    }
+}
+
+class Test {
+    public static int a_plus_b(Integer a, Integer b) {
+        return a + b;
+    }
+
+    public static int a_plus_b(Function<Object, Comparable> keymap, Object a, Object b) {
+        if (keymap.apply(a).compareTo(keymap.apply(b)) < 0) {
+            return -1;
+        } else if (keymap.apply(a).compareTo(keymap.apply(b)) > 0) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+}