# How hf_repo_files and hf_repo_git Tools Handle Repository Operations in ML Intern

> Discover how hf_repo_files and hf_repo_git tools manage repository operations for the ML Intern agent. Explore async interfaces for file CRUD and Git management.

- Repository: [Hugging Face/ml-intern](https://github.com/huggingface/ml-intern)
- Tags: how-to-guide
- Published: 2026-04-24

---

**The `hf_repo_files` and `hf_repo_git` tools provide async-enabled interfaces that wrap the Hugging Face Hub API to perform file-level CRUD operations and Git-style repository management, returning standardized markdown results to the ML Intern agent.**

ML Intern, Hugging Face's machine learning agent framework, ships with two complementary tools that enable language models to interact programmatically with Hub repositories. According to the `huggingface/ml-intern` source code, these tools abstract synchronous `huggingface_hub` calls into async-native operations while maintaining a uniform `ToolResult` contract for error handling and response formatting.

## Tool Architecture Overview

The repository tools follow a consistent async-first design pattern to prevent blocking the agent's event loop during Hub API calls.

### hf_repo_files Tool

Located in [`agent/tools/hf_repo_files_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/hf_repo_files_tool.py), this tool manages file-level operations on model, dataset, and space repositories. It implements four core operations—`list`, `read`, `upload`, and `delete`—by wrapping the synchronous `huggingface_hub.HfApi` and `hf_hub_download` methods.

All Hub API calls are executed through an `_async_call` helper that uses `asyncio.to_thread` to run blocking operations in a thread pool. The tool builds human-readable URLs using `_build_repo_url` and formats file sizes with `_format_size`. Results are returned as a `ToolResult` dictionary containing a markdown-formatted string, a result count, and an optional `isError` flag.

The public interface is defined by `HF_REPO_FILES_TOOL_SPEC`, which provides the JSON schema the agent must use when constructing requests.

### hf_repo_git Tool

Located in [`agent/tools/hf_repo_git_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/hf_repo_git_tool.py), this tool handles higher-level repository metadata and Git-style workflows. It supports branch and tag creation/deletion, reference listing, repository creation, and a complete PR lifecycle including `create_pr`, `list_prs`, `get_pr`, `merge_pr`, `close_pr`, `comment_pr`, and `change_pr_status`.

Like its counterpart, `hf_repo_git` routes operations through a dictionary of async handler methods and utilizes the same `_async_call` abstraction to wrap `HfApi` methods. It provides a comprehensive OpenAPI-like specification via `HF_REPO_GIT_TOOL_SPEC` and generates formatted links to branches, tags, and discussions using `_build_repo_url`.

## Execution Flow

When the ML Intern agent invokes either tool, the following architectural flow occurs:

1. **Request Routing** – The agent emits a JSON payload containing an `operation` key (e.g., `"list"` for files or `"create_branch"` for git).

2. **Tool Instantiation** – The router instantiates `HfRepoFilesTool` or `HfRepoGitTool`, injecting the current session `hf_token` for authentication.

3. **Handler Dispatch** – The tool's `execute()` method looks up the appropriate async handler from the internal `handlers` mapping and awaits its completion.

4. **Async Wrapping** – Inside each handler, synchronous Hub API calls are wrapped with `_async_call`, which delegates execution to a thread pool via `asyncio.to_thread`.

5. **Result Transformation** – Raw Hub API responses (such as lists of `RepoFile` objects, `RepoRefs`, or `Discussion` instances) are transformed into markdown strings suitable for direct display.

6. **Error Normalization** – Specific exceptions like `RepositoryNotFoundError` and `EntryNotFoundError` are caught and converted into `ToolResult` objects with `isError=True`, ensuring consistent error handling across the agent ecosystem.

## File Operations with hf_repo_files

The `hf_repo_files` tool enables precise file manipulation without local Git overhead.

### Supported Operations

- **`list`**: Enumerates files in a repository revision, returning a markdown table with file sizes and a link to the repo tree.
- **`read`**: Retrieves file contents (e.g., [`README.md`](https://github.com/huggingface/ml-intern/blob/main/README.md)) with optional truncation using the `max_chars` parameter.
- **`upload`**: Commits new files or updates existing ones, with optional PR creation via the `create_pr` boolean flag.
- **`delete`**: Removes files matching specified glob patterns (e.g., `"*.tmp"`, `"logs/"`).

### Error Handling

The tool catches `RepositoryNotFoundError` and `EntryNotFoundError` specifically, returning user-friendly error messages within the `ToolResult` structure. Generic exceptions are similarly trapped and formatted to prevent agent execution failures.

## Git Operations with hf_repo_git

The `hf_repo_git` tool provides programmatic access to repository branching and collaborative workflows.

### Branch and Tag Management

Operations include `create_branch`, `delete_branch`, `create_tag`, `delete_tag`, and `list_refs`. These map directly to `HfApi` methods but execute asynchronously and return formatted markdown summaries containing links to the specific refs.

### Pull Request Lifecycle

The tool supports the complete PR workflow:
- **Creation**: `create_pr` accepts `title`, `description`, and optional `draft` parameters.
- **Management**: `get_pr`, `list_prs`, and `change_pr_status` allow inspection and state modification.
- **Integration**: `merge_pr` supports squash and rebase strategies, while `comment_pr` enables discussion participation without leaving the agent context.

## Practical Usage Examples

Below are JSON payloads that the ML Intern agent sends to each tool. These can be executed through the tool router or replicated in a Python environment with the ML Intern dependencies installed.

### List Repository Files

```json
{
  "operation": "list",
  "repo_id": "gpt2",
  "repo_type": "model",
  "revision": "main"
}

```

This returns a markdown table of all files with sizes and a link to the repository tree.

### Read File Contents

```json
{
  "operation": "read",
  "repo_id": "gpt2",
  "repo_type": "model",
  "path": "README.md",
  "revision": "main",
  "max_chars": 5000
}

```

The result contains the file contents wrapped in a code block, truncated if exceeding `max_chars`.

### Upload with Pull Request

```json
{
  "operation": "upload",
  "repo_id": "my-org/my-model",
  "repo_type": "model",
  "path": "scripts/train.py",
  "content": "# training script\nprint('Hello')",

  "create_pr": true,
  "commit_message": "Add training script"
}

```

Setting `create_pr: true` generates a link to the newly created PR rather than committing directly to the branch.

### Delete Temporary Files

```json
{
  "operation": "delete",
  "repo_id": "my-org/my-model",
  "repo_type": "model",
  "patterns": ["*.tmp", "logs/"],
  "create_pr": false
}

```

This removes all matching files and returns a confirmation message.

### Create a Branch

```json
{
  "operation": "create_branch",
  "repo_id": "my-org/my-model",
  "repo_type": "model",
  "branch": "experiment",
  "from_rev": "main"
}

```

### List References

```json
{
  "operation": "list_refs",
  "repo_id": "my-org/my-model",
  "repo_type": "model"
}

```

### Open a Draft Pull Request

```json
{
  "operation": "create_pr",
  "repo_id": "my-org/my-model",
  "repo_type": "model",
  "title": "Add new evaluation script",
  "description": "This PR adds eval.py and updates the README."
}

```

### Merge an Existing PR

```json
{
  "operation": "merge_pr",
  "repo_id": "my-org/my-model",
  "repo_type": "model",
  "pr_num": 12,
  "comment": "Merging after review."
}

```

All JSON payloads return a `ToolResult` containing a `formatted` markdown string that the agent can render directly to the user.

## Summary

- **`hf_repo_files`** and **`hf_repo_git`** are async-native tools located in [`agent/tools/hf_repo_files_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/hf_repo_files_tool.py) and [`agent/tools/hf_repo_git_tool.py`](https://github.com/huggingface/ml-intern/blob/main/agent/tools/hf_repo_git_tool.py) respectively.
- Both tools wrap synchronous `huggingface_hub.HfApi` methods using an `_async_call` helper that executes via `asyncio.to_thread`.
- **File operations** include `list`, `read`, `upload`, and `delete` with support for PR-based workflows.
- **Git operations** cover branch/tag management and complete PR lifecycle control including creation, merging, and commenting.
- Errors such as `RepositoryNotFoundError` and `EntryNotFoundError` are normalized into consistent `ToolResult` objects with `isError=True`.
- The tools share a uniform JSON schema defined by `HF_REPO_FILES_TOOL_SPEC` and `HF_REPO_GIT_TOOL_SPEC`, enabling seamless integration with the ML Intern agent router.

## Frequently Asked Questions

### How do these tools prevent blocking the ML Intern agent during API calls?

Both tools implement an `_async_call` wrapper that delegates synchronous `Hugging Face Hub` API methods to a thread pool using `asyncio.to_thread`. This allows the agent's event loop to remain responsive while waiting for network I/O to complete, ensuring that other tools like `research_tool` or `papers_tool` can continue processing concurrently.

### What is the difference between `hf_repo_files` and `hf_repo_git`?

**`hf_repo_files`** focuses on blob-level file operations—listing directory contents, reading file text, uploading new versions, and deleting patterns—while **`hf_repo_git`** manages repository metadata and collaborative workflows such as branch creation, tag management, and the full pull request lifecycle. The former manipulates file contents; the latter manipulates repository structure and discussions.

### Can these tools create pull requests instead of direct commits?

Yes. When using the `upload` operation in `hf_repo_files` or various write operations in `hf_repo_git`, setting `create_pr: true` (or equivalent parameters) opens a pull request rather than committing directly to the target branch. The resulting `ToolResult` includes a markdown-formatted link to the newly created PR on Hugging Face Hub.

### What happens if a repository or file does not exist?

Both tools catch specific `huggingface_hub` exceptions—`RepositoryNotFoundError` and `EntryNotFoundError`—and convert them into `ToolResult` objects with `isError=True` and descriptive messages. This prevents stack traces from propagating to the agent and allows the language model to handle the error gracefully, often by suggesting alternative repository IDs or paths.