Files
coding-agent-gitea/gitea/tools/file_tools.py
T
Michael bf13a979c2 feat: add output truncation and offset paging to all large-output tools
- coding_tools: list_files (max_entries=200, sorted), run_command
  (max_chars=8000, output_offset), grep_search (max_lines=100, offset);
  added _truncate_output helper for run_command paging
- pr_tools: get_pull_request_diff / get_pull_request_patch now truncate
  at 15k chars with hunk-boundary awareness and char_offset paging;
  get_pull_request_comments gains limit/offset paging
- issue_tools: get_issue_comments gains limit/offset paging
- file_tools: get_file_content / get_file_content_with_ref now paginate
  by line (offset=1, limit=250), matching existing read_file convention;
  added _paginate_lines helper
- research_tools: fetch_url gains char_offset parameter; _smart_truncate
  now slices from an offset and embeds next char_offset in the footer
- gitea_tools facade: all new params threaded through
2026-06-28 19:57:14 +02:00

95 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Any
from gitea.client import GiteaClient
class FileTools:
"""Tools for Gitea file/content operations."""
def __init__(self, client: GiteaClient) -> None:
self._client = client
def _paginate_lines(
self,
content: str,
offset: int,
limit: int,
) -> str:
"""Return lines[offset-1 : offset-1+limit] with a paging footer if truncated.
Uses the same 1-indexed convention as CodingTools.read_file.
"""
lines: list[str] = content.splitlines()
total: int = len(lines)
start: int = offset - 1 # convert to 0-indexed
page: list[str] = lines[start : start + limit]
formatted: list[str] = [
f"{start + i + 1}: {line}" for i, line in enumerate(page)
]
result: str = "\n".join(formatted)
end_line: int = start + len(page)
if end_line < total:
next_offset: int = end_line + 1
result += (
f"\n\n[{total} lines total — showing lines {offset}{end_line}. "
f"Re-call with offset={next_offset} to read more.]"
)
return result
def get_file_content(
self,
owner: str,
repo: str,
path: str,
offset: int = 1,
limit: int = 250,
) -> str:
"""Get the content of a file from a Gitea repository with line paging.
Args:
offset: 1-indexed line to start from (default 1).
limit: Maximum number of lines to return (default 250).
"""
try:
content = self._client.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)}"
def get_file_content_with_ref(
self,
owner: str,
repo: str,
path: str,
ref: str = "master",
offset: int = 1,
limit: int = 250,
) -> str:
"""Get file content at a specific git ref with line paging.
Args:
ref: Branch, tag, or commit SHA (default 'master').
offset: 1-indexed line to start from (default 1).
limit: Maximum number of lines to return (default 250).
"""
try:
content = self._client.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)}"
def commit_file(self, owner: str, repo: str, path: str, message: str, content: str, branch: str) -> str:
try:
self._client.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)}"
def update_file(self, owner: str, repo: str, path: str, message: str, content: str, branch: str) -> str:
try:
self._client.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)}"