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 686678995c5e39f2fd0373624d85718c543eb39f 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:44:03 +0000 Subject: [PATCH 4/4] Patched patchwork/steps/DatabaseAgent/README.md --- patchwork/steps/DatabaseAgent/README.md | 56 +++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 patchwork/steps/DatabaseAgent/README.md diff --git a/patchwork/steps/DatabaseAgent/README.md b/patchwork/steps/DatabaseAgent/README.md new file mode 100644 index 000000000..f1b4992f0 --- /dev/null +++ b/patchwork/steps/DatabaseAgent/README.md @@ -0,0 +1,56 @@ +# Documentation: DatabaseAgent Module + +## Overview + +The `DatabaseAgent` module is designed to facilitate interaction with a database by generating and executing appropriate SQL queries. It uses machine learning to understand and interpret user tasks and generates an execution plan to gather and process necessary data from a database using the specified database dialect (e.g., SQL). + +The main functionality is encapsulated within a class called `DatabaseAgent`, which leverages the `AgenticStrategyV2` to dynamically generate responses to user tasks. This agent uses the `AioLlmClient` and `DatabaseQueryTool` to perform its operations, geared towards summarizing conversations and fetching data based on user prompts. + +## Inputs + +### DatabaseAgent Inputs Class + +In the file `typed.py`, the `DatabaseAgentInputs` class defines the input structure that the `DatabaseAgent` expects: + +- **task (str):** A string describing the task that needs completion. +- **db_dialect (str):** Specifies the type of SQL dialect the database uses (e.g., MySQL, PostgreSQL). +- **db_driver (str):** The database driver used for connections. +- **db_username (str):** Username for database authentication. +- **db_password (str):** Password for database authentication. +- **db_host (str):** Host address of the database. +- **db_port (int):** Port number for database connection. +- **db_name (str):** Name of the database. +- **db_params (dict):** Additional connection parameters. +- **db_driver_args (dict):** Additional driver-specific arguments. +- **prompt_value (Dict[str, Any]):** Dictionary holding values for prompt customization. +- **max_llm_calls (int):** Configures the maximum number of large language model calls. +- **openai_api_key (str):** API key for OpenAI services. +- **anthropic_api_key (str):** API key for Anthropic services. +- **google_api_key (str):** API key for Google services. +- **example_json (str):** A JSON example to guide response structure. + +## Outputs + +### DatabaseAgent Outputs Class + +Within `typed.py`, the `DatabaseAgentOutputs` class is introduced to outline the expected output format: + +- **request_tokens (int):** Number of tokens used in the request. +- **response_tokens (int):** Number of tokens received in the response. + +## DatabaseAgent Implementation + +### Core Functionality + +In `DatabaseAgent.py`, the `DatabaseAgent` class derives from the `Step` class and uses both `DatabaseAgentInputs` and `DatabaseAgentOutputs`. The class: + +- Initializes an agentic strategy to process user-provided tasks and database information. +- Sets up database query configurations through the `DatabaseQueryTool`. +- Employs the `mustache_render` utility to tailor command-line interactions and strategy prompts. +- Executes the task, restricting output operation to a maximum of ten results (`limit=10`). + +### `run` Method + +The `run` function executes the agent's strategy to fetch requested data and append execution usage metrics from the `AgenticStrategyV2`. + +By employing this module, users can expect an automated task execution environment, where high-level natural language prompts can seamlessly translate into concrete database operations. This setup is particularly useful for data analysis and management tasks that require flexible and interactive database querying capabilities.