fix: improve prompts, error messages, and workspace concurrency

- Externalize coordinator, notification, and planning prompts to separate files
- Add workspace mutex for concurrent file operations
- Improve error messages across file_tools, issue_tools, and pr_tools
- Add logging to tool modules for better debugging
- Update tests to match new error message strings
This commit is contained in:
meeks
2026-07-19 17:49:33 +02:00
committed by Michael
parent ee01487ce3
commit dfdd8c0931
11 changed files with 300 additions and 107 deletions
+50 -10
View File
@@ -1,8 +1,11 @@
import logging
import os
from pathlib import Path
from typing import Any
from gitea.client import GiteaClient
logger: logging.Logger = logging.getLogger("gitea-file-tools")
class FileTools:
"""Tools for Gitea file/content operations."""
@@ -67,18 +70,28 @@ class FileTools:
local_path: str | None = self._resolve_local_path(owner, repo, path)
if local_path and os.path.isfile(local_path):
try:
with open(local_path, 'r', encoding='utf-8', errors='replace') as f:
with open(local_path, "r", encoding="utf-8", errors="replace") as f:
raw: str = f.read()
return self._paginate_lines(raw, offset, limit)
except Exception:
pass
except Exception as exc:
logger.debug(
f"Local read failed for {owner}/{repo}/{path}: {exc}",
exc_info=True,
)
try:
content = self._client.files.get_file_content(owner, repo, path)
raw: str = "\n".join(content) if isinstance(content, list) else content
return self._paginate_lines(raw, offset, limit)
except Exception as e:
return f"Error getting file content: {str(e)}"
logger.error(
f"Failed to get file content for {owner}/{repo}/{path}: {e}",
exc_info=True,
)
return (
f"Error: Could not retrieve file '{path}' from {owner}/{repo}. "
f"Verify the file path and branch are correct. Details: {e}"
)
def get_file_content_with_ref(
self,
@@ -104,21 +117,34 @@ class FileTools:
if os.path.isdir(local_repo):
try:
import subprocess
result = subprocess.run(
["git", "-C", local_repo, "show", f"{ref}:{path}"],
capture_output=True, text=True, timeout=15,
capture_output=True,
text=True,
timeout=15,
)
if result.returncode == 0:
return self._paginate_lines(result.stdout, offset, limit)
except Exception:
pass
except Exception as exc:
logger.debug(
f"Local git show failed for {owner}/{repo}/{path}@{ref}: {exc}",
exc_info=True,
)
try:
content = self._client.files.get_file_content(owner, repo, path, ref)
raw: str = "\n".join(content) if isinstance(content, list) else content
return self._paginate_lines(raw, offset, limit)
except Exception as e:
return f"Error getting file content: {str(e)}"
logger.error(
f"Failed to get file content for {owner}/{repo}/{path}@{ref}: {e}",
exc_info=True,
)
return (
f"Error: Could not retrieve file '{path}' at ref '{ref}' from {owner}/{repo}. "
f"Verify the file path and ref are correct. Details: {e}"
)
def commit_file(
self, owner: str, repo: str, path: str, message: str, content: str, branch: str
@@ -127,7 +153,14 @@ class FileTools:
self._client.files.update_file(owner, repo, path, message, content, branch)
return f"File '{path}' committed successfully to {owner}/{repo}."
except Exception as e:
return f"Error committing file: {str(e)}"
logger.error(
f"Failed to commit file '{path}' to {owner}/{repo}@{branch}: {e}",
exc_info=True,
)
return (
f"Error: Could not commit file '{path}' to {owner}/{repo} on branch '{branch}'. "
f"Check for conflicts or permission issues. Details: {e}"
)
def update_file(
self, owner: str, repo: str, path: str, message: str, content: str, branch: str
@@ -136,4 +169,11 @@ class FileTools:
self._client.files.update_file(owner, repo, path, message, content, branch)
return f"File '{path}' updated in {owner}/{repo}."
except Exception as e:
return f"Error updating file: {str(e)}"
logger.error(
f"Failed to update file '{path}' in {owner}/{repo}@{branch}: {e}",
exc_info=True,
)
return (
f"Error: Could not update file '{path}' in {owner}/{repo} on branch '{branch}'. "
f"Check for conflicts or permission issues. Details: {e}"
)