diff --git a/patchwork/common/tools/git_tool.py b/patchwork/common/tools/git_tool.py new file mode 100644 index 000000000..d5acbfa05 --- /dev/null +++ b/patchwork/common/tools/git_tool.py @@ -0,0 +1,49 @@ +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. +E.g. +[\"commit\", \"-m\", \"A commit message\"] to commit changes with a commit message. +[\"add\", \".\"] to stage all changed files. +""", + } + }, + "required": ["args"], + }, + } + + def execute(self, args: list[str]) -> str: + env = os.environ.copy() + p = subprocess.run( + ["git", *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. diff --git a/patchwork/steps/GitHubAgent/README.md b/patchwork/steps/GitHubAgent/README.md new file mode 100644 index 000000000..dbf184f93 --- /dev/null +++ b/patchwork/steps/GitHubAgent/README.md @@ -0,0 +1,66 @@ +# Documentation: GitHubAgent Module + +This module is part of the Patchwork project and focuses on the implementation of a GitHub automation agent, which is leveraged to interact with GitHub repositories and obtain necessary data through a conversation-based agentic strategy. It utilizes both new and existing machine learning models and tools such as the GitHub CLI. + +## GitHubAgent.py + +### Description + +This script defines a `GitHubAgent` class which inherits from the `Step` class. It integrates several tools and strategies to facilitate GitHub tasks via AI-driven conversations. The agent is configured to execute specific tasks using the GitHub CLI and provides summaries of the actions undertaken. + +### Inputs + +- **`github_api_key`** (`str`): Required API key for accessing GitHub. +- **`task`** (`str`): The task to be executed by the GitHub agent. +- **Optional Inputs:** + - **`base_path`** (`str`): The base directory path for operations. Defaults to the current working directory. + - **`prompt_value`** (`Dict[str, Any]`): Data to be used in task prompt rendering. + - **`example_json`** (`str`): Example JSON structure showing a summary of actions. + - **`max_llm_calls`** (`int`): Configuration for maximum large language model calls. + - **API Keys**: (Can use OpenAI, Anthropic, or Google API keys as alternatives) + +### Outputs + +- **`request_tokens`** (`int`): Number of tokens consumed during API requests. +- **`response_tokens`** (`int`): Number of tokens in API responses. + +### Usage + +The class is initialized with the specified inputs and constructs an agentic strategy that simulates interaction with a GitHub repository. The outcome of the agent's actions are returned alongside token usage statistics. + +--- + +## typed.py + +### Description + +This file contains type definitions used by the `GitHubAgent`. It defines the structures for input and output data using Python's `TypedDict`. + +### Inputs + +- **`GitHubAgentInputs`**: A TypedDict class for input validation and structured configuration. + - Includes fields for API keys, task descriptions, and configuration flags. + +### Outputs + +- **`GitHubAgentOutputs`**: A TypedDict class defining fields for tracking the number of tokens used in requests and responses. + +### Usage + +The types defined here ensure consistent and type-safe usage of inputs and outputs in the `GitHubAgent`. + +--- + +## __init__.py + +### Description + +This file serves as the package initializer for the `GitHubAgent` module. It currently does not include any code but typically indicates a package directory in Python. + +### Usage + +Acts as an entry point to load the module's other components correctly when imported. + +--- + +By leveraging the components defined in these files, developers can automate interactions with GitHub, execute tasks, and retrieve data programmatically with minimal manual input. 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"