fix(dev.py): fix CRUD operation bugs

- Fixed redundant __user__ checks in _get_token, _get_repo, _get_branch, _get_org
- Fixed merge_pull_request: proper conflict detection (409), merged status check, and empty response handling
- Fixed update_file: proper 404 handling before raise_for_status
- Fixed delete_file: proper 404 handling before raise_for_status
- Updated version to 1.4.1 with changelog

Refs: bug hunt fix
This commit is contained in:
2026-01-15 17:43:06 +00:00
parent dbfeca8271
commit 7f35b8fac4

View File

@@ -1,11 +1,16 @@
"""
title: Gitea Dev - Native Mode Optimized
author: Jeff Smith + Claude + minimax + kimi-k2
version: 1.4.0
version: 1.4.1
license: MIT
description: Interact with Gitea repositories - native tool calling optimized for high-tier LLMs with robust error handling
requirements: pydantic, httpx
changelog:
1.4.1:
- Fixed redundant __user__ checks in _get_token, _get_repo, _get_branch, _get_org
- Fixed merge_pull_request: proper conflict detection, merged status check, and empty response handling
- Fixed delete_file: proper 404 handling before raise_for_status
- Fixed update_file: proper 404 handling before raise_for_status
1.4.0:
- Added CRUD operations for Issues (get, update, close, reopen, delete, comments)
- Added CRUD operations for Pull Requests (get, update, merge, comments)
@@ -102,7 +107,8 @@ class Tools:
def _get_token(self, __user__: dict = None) -> str:
"""Extract Gitea token from user context with robust handling"""
if __user__ and "valves" in __user__:
user_valves = __user__.get("valves") if __user__ else None
user_valves = __user__.get("valves")
if user_valves:
return user_valves.GITEA_TOKEN
return ""
@@ -132,7 +138,8 @@ class Tools:
if repo:
return repo
if __user__ and "valves" in __user__:
user_valves = __user__.get("valves") if __user__ else None
user_valves = __user__.get("valves")
if user_valves:
if self.valves.ALLOW_USER_OVERRIDES and user_valves.USER_DEFAULT_REPO:
return user_valves.USER_DEFAULT_REPO
return self.valves.DEFAULT_REPO
@@ -142,7 +149,8 @@ class Tools:
if branch:
return branch
if __user__ and "valves" in __user__:
user_valves = __user__.get("valves") if __user__ else None
user_valves = __user__.get("valves")
if user_valves:
if self.valves.ALLOW_USER_OVERRIDES and user_valves.USER_DEFAULT_BRANCH:
return user_valves.USER_DEFAULT_BRANCH
return self.valves.DEFAULT_BRANCH
@@ -152,7 +160,8 @@ class Tools:
if org:
return org
if __user__ and "valves" in __user__:
user_valves = __user__.get("valves") if __user__ else None
user_valves = __user__.get("valves")
if user_valves:
if self.valves.ALLOW_USER_OVERRIDES and user_valves.USER_DEFAULT_ORG:
return user_valves.USER_DEFAULT_ORG
return self.valves.DEFAULT_ORG
@@ -2419,14 +2428,33 @@ class Tools:
json={"merge_strategy": merge_strategy},
)
# Check for conflict before raise_for_status
if response.status_code == 409:
try:
error_data = response.json()
error_msg = error_data.get("message", "Merge conflicts detected")
except Exception:
error_msg = "Merge conflicts detected"
return f"Error: PR #{pr_number} cannot be merged due to conflicts.\n\nDetails: {error_msg}"
if response.status_code == 405:
return "Error: PR cannot be merged. Check if it's already merged or has conflicts."
try:
error_data = response.json()
error_msg = error_data.get("message", "PR cannot be merged")
except Exception:
error_msg = "PR cannot be merged"
return f"Error: PR #{pr_number} cannot be merged. {error_msg}"
response.raise_for_status()
result = response.json() if response.text else {}
merged = result.get("merged", True)
commit_sha = result.get("merge_commit", {}).get("sha", "")[:8]
# Handle successful merge response (may be empty or have merge details)
if not response.text:
merged = True
commit_sha = ""
else:
result = response.json() if response.text else {}
merged = result.get("merged", True) # Default to True if key missing
commit_sha = result.get("merge_commit", {}).get("sha", "")[:8] if result else ""
if __event_emitter__:
await __event_emitter__(
@@ -2446,10 +2474,12 @@ class Tools:
)
return output
else:
return f"**PR #{pr_number} Merge Result:**\n\n{result}\n"
return f"**PR #{pr_number} Merge Result:**\n\nMerge operation returned success=false"
except httpx.HTTPStatusError as e:
error_msg = self._format_error(e, f"PR #{pr_number} merge")
if e.response.status_code == 409:
return f"Error: PR #{pr_number} cannot be merged due to conflicts."
if e.response.status_code == 405:
return f"Error: PR #{pr_number} cannot be merged. It may already be merged or have merge conflicts."
return f"Error: Failed to merge PR. {error_msg}"