huggingface/ml-internPublic

🤗 ml-intern: an open-source ML engineer that reads papers, trains models, and ships ML models

AI summary: A terminal-based AI agent configured for machine learning operations using Hugging Face endpoints and local models.

Stars
10.7K
+3 today
Forks
1.2K
Watchers
44
Open issues
32
Open PRs
37
Contributors
~17
Commits
490
Branches
57

PythonApache-2.0Created Oct 30, 2025Last push 7d ago+15 stars this week+19 this month

Star history

since Apr 19, 2026
05K10KApr 2026May 2026Jun 2026Aug 2026
10.7K stars as of Aug 7, 2026, tracked back to Apr 19, 2026. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulAugMonWedFri2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 3 commits2025-10-29: 0 commits2025-10-30: 4 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-08: 0 commits2025-11-09: 0 commits2025-11-10: 2 commits2025-11-11: 2 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 6 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 1 commit2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 3 commits2025-11-26: 0 commits2025-11-27: 5 commits2025-11-28: 2 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 3 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 1 commit2025-12-19: 1 commit2025-12-20: 2 commits2025-12-21: 0 commits2025-12-22: 5 commits2025-12-23: 1 commit2025-12-24: 1 commit2025-12-25: 0 commits2025-12-26: 1 commit2025-12-27: 0 commits2025-12-28: 1 commit2025-12-29: 5 commits2025-12-30: 5 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 4 commits2026-01-03: 5 commits2026-01-04: 4 commits2026-01-05: 4 commits2026-01-06: 1 commit2026-01-07: 11 commits2026-01-08: 5 commits2026-01-09: 0 commits2026-01-10: 1 commit2026-01-11: 0 commits2026-01-12: 6 commits2026-01-13: 12 commits2026-01-14: 15 commits2026-01-15: 7 commits2026-01-16: 2 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 1 commit2026-01-20: 3 commits2026-01-21: 2 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 1 commit2026-01-27: 4 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 1 commit2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 0 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 2 commits2026-02-14: 0 commits2026-02-15: 0 commits2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 0 commits2026-02-25: 4 commits2026-02-26: 5 commits2026-02-27: 8 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 0 commits2026-03-03: 0 commits2026-03-04: 2 commits2026-03-05: 10 commits2026-03-06: 1 commit2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 7 commits2026-03-10: 7 commits2026-03-11: 7 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 1 commit2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 3 commits2026-03-24: 11 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 5 commits2026-04-01: 7 commits2026-04-02: 0 commits2026-04-03: 29 commits2026-04-04: 0 commits2026-04-05: 18 commits2026-04-06: 10 commits2026-04-07: 0 commits2026-04-08: 5 commits2026-04-09: 2 commits2026-04-10: 0 commits2026-04-11: 0 commits2026-04-12: 0 commits2026-04-13: 2 commits2026-04-14: 15 commits2026-04-15: 0 commits2026-04-16: 1 commit2026-04-17: 2 commits2026-04-18: 0 commits2026-04-19: 0 commits2026-04-20: 4 commits2026-04-21: 3 commits2026-04-22: 15 commits2026-04-23: 5 commits2026-04-24: 3 commits2026-04-25: 5 commits2026-04-26: 2 commits2026-04-27: 21 commits2026-04-28: 7 commits2026-04-29: 1 commit2026-04-30: 3 commits2026-05-01: 7 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 6 commits2026-05-05: 3 commits2026-05-06: 7 commits2026-05-07: 2 commits2026-05-08: 7 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 2 commits2026-05-12: 0 commits2026-05-13: 1 commit2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 0 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 5 commits2026-06-02: 2 commits2026-06-03: 3 commits2026-06-04: 1 commit2026-06-05: 2 commits2026-06-06: 0 commits2026-06-07: 10 commits2026-06-08: 5 commits2026-06-09: 2 commits2026-06-10: 1 commit2026-06-11: 0 commits2026-06-12: 6 commits2026-06-13: 1 commit2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 3 commits2026-06-18: 2 commits2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 0 commits2026-06-24: 0 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 0 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 0 commits2026-07-04: 0 commits2026-07-05: 0 commits2026-07-06: 0 commits2026-07-07: 0 commits2026-07-08: 0 commits2026-07-09: 0 commits2026-07-10: 0 commits2026-07-11: 0 commits2026-07-12: 0 commits2026-07-13: 0 commits2026-07-14: 0 commits2026-07-15: 0 commits2026-07-16: 0 commits2026-07-17: 0 commits2026-07-18: 0 commits2026-07-19: 0 commits2026-07-20: 0 commits2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 0 commits2026-07-25: 0 commits2026-07-26: 0 commits2026-07-27: 0 commits2026-07-28: 0 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 0 commits2026-08-01: 0 commits2026-08-02: 0 commits2026-08-03: 0 commits2026-08-04: 0 commits2026-08-05: 0 commits2026-08-06: 0 commits2026-08-07: 0 commits2026-08-08: 0 commits
454 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Widely adopted

    10,719 stars

  • Permissive license

    Apache-2.0

  • Continuous integration

    Automated checks passing

  • Repeat trending

    3 trending appearances

What ml-intern does

ML Intern provides a command-line interface that connects to various LLM providers (including Hugging Face routers, OpenAI, and local endpoints like Ollama) to execute machine learning tasks. It handles operations via an internal agentic loop that processes tool calls and manages conversation context up to 170k tokens, automatically compacting history when needed. The runtime supports executing code directly on the local filesystem or securely inside Hugging Face Spaces using a sandbox tool runtime. Furthermore, it automatically uploads session traces to a private Hugging Face dataset for observability, while providing integrations with Slack for out-of-band notifications on required approvals or errors.

This tool is aimed at machine learning engineers and researchers who require an AI assistant deeply integrated with the Hugging Face ecosystem and local hardware. It is ideal for users who want to safely automate model testing and script execution with robust trace visibility.

  • Agentic loop: Automatically manages iterative tool executions, auto-compaction, and doom loop detection within a session context manager.
  • Multi-model support: Connects dynamically to Hugging Face routers, OpenAI, and local inference endpoints like Ollama, vLLM, and LM Studio.
  • Sandbox execution: Optionally runs commands and scripts within isolated Hugging Face Spaces instead of the local filesystem for secure remote testing.
  • Trace sharing: Auto-uploads conversation sessions and tool calls to a private dataset on Hugging Face using the Claude Code JSONL format.
  • Slack notifications: Configures out-of-band status alerts to notify operators when human approval is required for sensitive operations.

Where teams use it

Local model orchestration

Developers use ML Intern to run agents entirely offline by configuring local endpoint routing to tools like Ollama or LM Studio.

Remote script testing

Machine learning engineers run training scripts safely inside dynamically provisioned Hugging Face Spaces using the sandbox tool runtime.

Automated workflow observability

Teams share agent traces and execution histories by viewing auto-uploaded datasets via the Hugging Face Agent Trace Viewer.

Human-in-the-loop operations

Operators rely on the built-in Slack integration to approve destructive local actions or high-cost jobs asynchronously.

Getting started: ml-intern --model moonshotai/Kimi-K2.7-Code:novita "your prompt"

README

main branch

smolagents logo

License Website

ML Intern

An ML intern that autonomously researches, writes, and ships good quality ML related code using the Hugging Face ecosystem — with deep access to docs, papers, datasets, and cloud compute.

Quick Start

Installation

git clone git@github.com:huggingface/ml-intern.git
cd ml-intern
uv sync
uv tool install -e .

That's it. Now ml-intern works from any directory:

ml-intern

Create a .env file in the project root (or export these in your shell):

HF_TOKEN=<your-hugging-face-token> # HF Router inference + Hub actions
GITHUB_TOKEN=<github-personal-access-token>

All API-based model calls go through Hugging Face Inference Providers, so your HF_TOKEN must be allowed to make Inference Provider calls. If no HF_TOKEN is set, the CLI will prompt you to paste one on first launch unless you start on a local model. To get a GITHUB_TOKEN follow the tutorial here. See the local models section below for instructions on using agents that run on your hardware.

Usage

Interactive mode (start a chat session):

ml-intern

Headless mode (single prompt, auto-approve):

ml-intern "fine-tune llama on my dataset"

Options:

ml-intern --sandbox-tools "your prompt"                         # use HF Space sandbox tools
ml-intern --max-iterations 100 "your prompt"
ml-intern --no-stream "your prompt"
# Change model
ml-intern --model moonshotai/Kimi-K2.7-Code:novita "your prompt"
ml-intern --model openai/gpt-5.5:fal-ai "your prompt"

Run ml-intern then /model to see the full list of suggested model ids (Claude, GPT, HF Router models like MiniMax, Kimi, GLM, DeepSeek, and local model prefixes).

Hosted inference is billed to the active Hugging Face user. See below on how to run ml-intern with local models.

Local models

Local model support uses OpenAI-compatible HTTP endpoints through LiteLLM. The agent does not load model weights directly from disk; start your inference server first, then select it with a provider-specific model prefix:

ml-intern --model ollama/llama3.1:8b "your prompt"
ml-intern --model vllm/meta-llama/Llama-3.1-8B-Instruct "your prompt"

Inside interactive mode, switch with /model:

/model ollama/llama3.1:8b
/model lm_studio/google/gemma-3-4b
/model llamacpp/llama-3.1-8b-instruct

Supported local prefixes are ollama/, vllm/, lm_studio/, and llamacpp/.

LOCAL_LLM_BASE_URL=http://localhost:8000
LOCAL_LLM_API_KEY=<optional-local-api-key>

Set LOCAL_LLM_BASE_URL and optional LOCAL_LLM_API_KEY to use one shared local endpoint, or override a specific provider with its matching *_BASE_URL / *_API_KEY variable, such as OLLAMA_BASE_URL or VLLM_API_KEY. Provider-specific variables take precedence over the shared local variables. Base URLs may include or omit /v1.

CLI tool runtime:

By default, the CLI runs bash, read, write, and edit on your local filesystem. To use HF Space sandbox tools instead, including sandbox_create, opt in with --sandbox-tools:

ml-intern --sandbox-tools "test this training script in a GPU sandbox"
ml-intern --model llamacpp/ggml-org/gemma-3-1b-it-GGUF --sandbox-tools

Sandbox tool runtime requires HF_TOKEN, even when the selected model is local, because it creates private HF Spaces. You can also make sandbox tools your CLI default in ~/.config/ml-intern/cli_agent_config.json:

{ "tool_runtime": "sandbox" }

Use the default local runtime when you want tools to inspect or edit files in your checkout. Use sandbox runtime when you want the agent to create or replace an HF Space sandbox, test code remotely, or request GPU sandbox hardware before launching larger HF Jobs.

Sharing Traces

Every session is auto-uploaded to your own private Hugging Face dataset in Claude Code JSONL format, which the HF Agent Trace Viewer auto-detects so you can browse turns, tool calls, and model responses directly on the Hub.

By default the dataset is named {your-hf-username}/ml-intern-sessions and is created private. You can flip it to public from inside the CLI:

/share-traces            # show current visibility + dataset URL
/share-traces public     # publish (anyone can view)
/share-traces private    # lock it back down

You can also flip visibility from the dataset page on huggingface.co — the agent honours whatever you set there for subsequent uploads.

To opt out entirely, set in your CLI config (e.g. configs/cli_agent_config.json or ~/.config/ml-intern/cli_agent_config.json):

{ "share_traces": false }

To override the destination repo, set:

{ "personal_trace_repo_template": "{hf_user}/my-custom-traces" }

The shared smolagents/ml-intern-sessions dataset is unrelated and only receives anonymized telemetry rows used by the backend KPI scheduler.

Supported Gateways

ML Intern currently supports one-way notification gateways from CLI sessions. These gateways send out-of-band status updates; they do not accept inbound chat messages.

Slack

Slack notifications use the Slack Web API to post messages when the agent needs approval, hits an error, or completes a turn. Create a Slack app with a bot token that has chat:write, invite the bot to the target channel, then set:

SLACK_BOT_TOKEN=xoxb-...
SLACK_CHANNEL_ID=C...

The CLI automatically creates a slack.default destination when both variables are present. Optional environment variables for the env-only default:

ML_INTERN_SLACK_NOTIFICATIONS=false
ML_INTERN_SLACK_DESTINATION=slack.ops
ML_INTERN_SLACK_AUTO_EVENTS=approval_required,error,turn_complete
ML_INTERN_SLACK_ALLOW_AGENT_TOOL=true
ML_INTERN_SLACK_ALLOW_AUTO_EVENTS=true

For a persistent user-level config, put overrides in ~/.config/ml-intern/cli_agent_config.json or point ML_INTERN_CLI_CONFIG at a JSON file:

{
  "messaging": {
    "enabled": true,
    "auto_event_types": ["approval_required", "error", "turn_complete"],
    "destinations": {
      "slack.ops": {
        "provider": "slack",
        "token": "${SLACK_BOT_TOKEN}",
        "channel": "${SLACK_CHANNEL_ID}",
        "allow_agent_tool": true,
        "allow_auto_events": true
      }
    }
  }
}

Architecture

Component Overview

┌─────────────────────────────────────────────────────────────┐
│                         User/CLI                            │
└────────────┬─────────────────────────────────────┬──────────┘
             │ Operations                          │ Events
             ↓ (user_input, exec_approval,         ↑
      submission_queue  interrupt, compact, ...)  event_queue
             │                                          │
             ↓                                          │
┌────────────────────────────────────────────────────┐  │
│            submission_loop (agent_loop.py)         │  │
│  ┌──────────────────────────────────────────────┐  │  │
│  │  1. Receive Operation from queue             │  │  │
│  │  2. Route to handler (run_agent/compact/...) │  │  │
│  └──────────────────────────────────────────────┘  │  │
│                      ↓                             │  │
│  ┌──────────────────────────────────────────────┐  │  │
│  │         Handlers.run_agent()                 │  ├──┤
│  │                                              │  │  │
│  │  ┌────────────────────────────────────────┐  │  │  │
│  │  │  Agentic Loop (max 300 iterations)     │  │  │  │
│  │  │                                        │  │  │  │
│  │  │  ┌──────────────────────────────────┐  │  │  │  │
│  │  │  │ Session                          │  │  │  │  │
│  │  │  │  ┌────────────────────────────┐  │  │  │  │  │
│  │  │  │  │ ContextManager             │  │  │  │  │  │
│  │  │  │  │ • Message history          │  │  │  │  │  │
│  │  │  │  │   (litellm.Message[])      │  │  │  │  │  │
│  │  │  │  │ • Auto-compaction (170k)   │  │  │  │  │  │
│  │  │  │  │ • Session upload to HF     │  │  │  │  │  │
│  │  │  │  └────────────────────────────┘  │  │  │  │  │
│  │  │  │                                  │  │  │  │  │
│  │  │  │  ┌────────────────────────────┐  │  │  │  │  │
│  │  │  │  │ ToolRouter                 │  │  │  │  │  │
│  │  │  │  │  ├─ HF docs & research     │  │  │  │  │  │
│  │  │  │  │  ├─ HF repos, datasets,    │  │  │  │  │  │
│  │  │  │  │  │  jobs, papers           │  │  │  │  │  │
│  │  │  │  │  ├─ GitHub code search     │  │  │  │  │  │
│  │  │  │  │  ├─ Sandbox & local tools  │  │  │  │  │  │
│  │  │  │  │  ├─ Planning               │  │  │  │  │  │
│  │  │  │  │  └─ MCP server tools       │  │  │  │  │  │
│  │  │  │  └────────────────────────────┘  │  │  │  │  │
│  │  │  └──────────────────────────────────┘  │  │  │  │
│  │  │                                        │  │  │  │
│  │  │  ┌──────────────────────────────────┐  │  │  │  │
│  │  │  │ Doom Loop Detector               │  │  │  │  │
│  │  │  │ • Detects repeated tool patterns │  │  │  │  │
│  │  │  │ • Injects corrective prompts     │  │  │  │  │
│  │  │  └──────────────────────────────────┘  │  │  │  │
│  │  │                                        │  │  │  │
│  │  │  Loop:                                 │  │  │  │
│  │  │    1. LLM call (litellm.acompletion)   │  │  │  │
│  │  │       ↓                                │  │  │  │
│  │  │    2. Parse tool_calls[]               │  │  │  │
│  │  │       ↓                                │  │  │  │
│  │  │    3. Approval check                   │  │  │  │
│  │  │       (jobs, sandbox, destructive ops) │  │  │  │
│  │  │       ↓                                │  │  │  │
│  │  │    4. Execute via ToolRouter           │  │  │  │
│  │  │       ↓                                │  │  │  │
│  │  │    5. Add results to ContextManager    │  │  │  │
│  │  │       ↓                                │  │  │  │
│  │  │    6. Repeat if tool_calls exist       │  │  │  │
│  │  └────────────────────────────────────────┘  │  │  │
│  └──────────────────────────────────────────────┘  │  │
└────────────────────────────────────────────────────┴──┘

Agentic Loop Flow

User Message
     ↓
[Add to ContextManager]
     ↓
     ╔═══════════════════════════════════════════╗
     ║      Iteration Loop (max 300)             ║
     ║                                           ║
     ║  Get messages + tool specs                ║
     ║         ↓                                 ║
     ║  litellm.acompletion()                    ║
     ║         ↓                                 ║
     ║  Has tool_calls? ──No──> Done             ║
     ║         │                                 ║
     ║        Yes                                ║
     ║         ↓                                 ║
     ║  Add assistant msg (with tool_calls)      ║
     ║         ↓                                 ║
     ║  Doom loop check                          ║
     ║         ↓                                 ║
     ║  For each tool_call:                      ║
     ║    • Needs approval? ──Yes──> Wait for    ║
     ║    │                         user confirm ║
     ║    No                                     ║
     ║    ↓                                      ║
     ║    • ToolRouter.execute_tool()            ║
     ║    • Add result to ContextManager         ║
     ║         ↓                                 ║
     ║  Continue loop ─────────────────┐         ║
     ║         ↑                       │         ║
     ║         └───────────────────────┘         ║
     ╚═══════════════════════════════════════════╝

Events

The agent emits the following events via event_queue:

  • processing - Starting to process user input
  • ready - Agent is ready for input
  • assistant_chunk - Streaming token chunk
  • assistant_message - Complete LLM response text
  • assistant_stream_end - Token stream finished
  • tool_call - Tool being called with arguments
  • tool_output - Tool execution result
  • tool_log - Informational tool log message
  • tool_state_change - Tool execution state transition
  • approval_required - Requesting user approval for sensitive operations
  • turn_complete - Agent finished processing
  • error - Error occurred during processing
  • interrupted - Agent was interrupted
  • compacted - Context was compacted
  • undo_complete - Undo operation completed
  • shutdown - Agent shutting down

Development

Pre-commit Checks

Run Ruff before every commit:

uv run ruff check .
uv run ruff format --check .

If the format check fails, run uv run ruff format . and re-run the checks before committing.

Adding Built-in Tools

Edit agent/core/tools.py:

def create_builtin_tools() -> list[ToolSpec]:
    return [
        ToolSpec(
            name="your_tool",
            description="What your tool does",
            parameters={
                "type": "object",
                "properties": {
                    "param": {"type": "string", "description": "Parameter description"}
                },
                "required": ["param"]
            },
            handler=your_async_handler
        ),
        # ... existing tools
    ]

Adding MCP Servers

Edit configs/cli_agent_config.json for CLI defaults, or configs/frontend_agent_config.json for web-session defaults:

{
  "model_name": "zai-org/GLM-5.2:novita",
  "mcpServers": {
    "your-server-name": {
      "transport": "http",
      "url": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${YOUR_TOKEN}"
      }
    }
  }
}

Note: Environment variables like ${YOUR_TOKEN} are auto-substituted from .env.

Cite ml-intern

If you use ml-intern in your work, please cite it by using the following BibTeX entry or similar.

@Misc{ml-intern,
  title =        {ml-intern: an agent that autonomously researches, writes, and ships good quality ML related code using the Hugging Face ecosystem},
  author =       {Aksel Joonas Reedi, Henri Bonamy, Yoan Di Cosmo, Leandro von Werra, Lewis Tunstall},
  howpublished = {\url{https://github.com/huggingface/ml-intern}},
  year =         {2026}
}
View on GitHub

Recent activity

commits and pull requests

Commits per week

last 52 weeks
420Week of 2025-08-10: 0 commitsWeek of 2025-08-17: 0 commitsWeek of 2025-08-24: 0 commitsWeek of 2025-08-31: 0 commitsWeek of 2025-09-07: 0 commitsWeek of 2025-09-14: 0 commitsWeek of 2025-09-21: 0 commitsWeek of 2025-09-28: 0 commitsWeek of 2025-10-05: 0 commitsWeek of 2025-10-12: 0 commitsWeek of 2025-10-19: 0 commitsWeek of 2025-10-26: 7 commitsWeek of 2025-11-02: 0 commitsWeek of 2025-11-09: 10 commitsWeek of 2025-11-16: 1 commitsWeek of 2025-11-23: 10 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 3 commitsWeek of 2025-12-14: 4 commitsWeek of 2025-12-21: 8 commitsWeek of 2025-12-28: 20 commitsWeek of 2026-01-04: 26 commitsWeek of 2026-01-11: 42 commitsWeek of 2026-01-18: 6 commitsWeek of 2026-01-25: 5 commitsWeek of 2026-02-01: 1 commitsWeek of 2026-02-08: 2 commitsWeek of 2026-02-15: 0 commitsWeek of 2026-02-22: 17 commitsWeek of 2026-03-01: 13 commitsWeek of 2026-03-08: 21 commitsWeek of 2026-03-15: 1 commitsWeek of 2026-03-22: 14 commitsWeek of 2026-03-29: 41 commitsWeek of 2026-04-05: 35 commitsWeek of 2026-04-12: 20 commitsWeek of 2026-04-19: 35 commitsWeek of 2026-04-26: 41 commitsWeek of 2026-05-03: 25 commitsWeek of 2026-05-10: 3 commitsWeek of 2026-05-17: 0 commitsWeek of 2026-05-24: 0 commitsWeek of 2026-05-31: 13 commitsWeek of 2026-06-07: 25 commitsWeek of 2026-06-14: 5 commitsWeek of 2026-06-21: 0 commitsWeek of 2026-06-28: 0 commitsWeek of 2026-07-05: 0 commitsWeek of 2026-07-12: 0 commitsWeek of 2026-07-19: 0 commitsWeek of 2026-07-26: 0 commitsWeek of 2026-08-02: 0 commitsAug 10, 2025Aug 2, 2026
454 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 0 commitsSun 1:00 — 0 commitsSun 2:00 — 0 commitsSun 3:00 — 0 commitsSun 4:00 — 0 commitsSun 5:00 — 0 commitsSun 6:00 — 0 commitsSun 7:00 — 0 commitsSun 8:00 — 0 commitsSun 9:00 — 0 commitsSun 10:00 — 0 commitsSun 11:00 — 2 commitsSun 12:00 — 2 commitsSun 13:00 — 0 commitsSun 14:00 — 0 commitsSun 15:00 — 1 commitsSun 16:00 — 0 commitsSun 17:00 — 3 commitsSun 18:00 — 1 commitsSun 19:00 — 3 commitsSun 20:00 — 3 commitsSun 21:00 — 8 commitsSun 22:00 — 10 commitsSun 23:00 — 2 commitsMon 0:00 — 2 commitsMon 1:00 — 7 commitsMon 2:00 — 1 commitsMon 3:00 — 0 commitsMon 4:00 — 0 commitsMon 5:00 — 0 commitsMon 6:00 — 1 commitsMon 7:00 — 0 commitsMon 8:00 — 2 commitsMon 9:00 — 3 commitsMon 10:00 — 7 commitsMon 11:00 — 6 commitsMon 12:00 — 5 commitsMon 13:00 — 3 commitsMon 14:00 — 11 commitsMon 15:00 — 7 commitsMon 16:00 — 16 commitsMon 17:00 — 6 commitsMon 18:00 — 0 commitsMon 19:00 — 1 commitsMon 20:00 — 2 commitsMon 21:00 — 2 commitsMon 22:00 — 4 commitsMon 23:00 — 3 commitsTue 0:00 — 0 commitsTue 1:00 — 1 commitsTue 2:00 — 3 commitsTue 3:00 — 0 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 1 commitsTue 7:00 — 3 commitsTue 8:00 — 12 commitsTue 9:00 — 0 commitsTue 10:00 — 1 commitsTue 11:00 — 7 commitsTue 12:00 — 7 commitsTue 13:00 — 2 commitsTue 14:00 — 7 commitsTue 15:00 — 11 commitsTue 16:00 — 9 commitsTue 17:00 — 7 commitsTue 18:00 — 3 commitsTue 19:00 — 4 commitsTue 20:00 — 6 commitsTue 21:00 — 4 commitsTue 22:00 — 1 commitsTue 23:00 — 1 commitsWed 0:00 — 0 commitsWed 1:00 — 0 commitsWed 2:00 — 0 commitsWed 3:00 — 0 commitsWed 4:00 — 0 commitsWed 5:00 — 0 commitsWed 6:00 — 0 commitsWed 7:00 — 0 commitsWed 8:00 — 2 commitsWed 9:00 — 3 commitsWed 10:00 — 1 commitsWed 11:00 — 6 commitsWed 12:00 — 20 commitsWed 13:00 — 8 commitsWed 14:00 — 4 commitsWed 15:00 — 5 commitsWed 16:00 — 9 commitsWed 17:00 — 17 commitsWed 18:00 — 4 commitsWed 19:00 — 6 commitsWed 20:00 — 2 commitsWed 21:00 — 0 commitsWed 22:00 — 1 commitsWed 23:00 — 0 commitsThu 0:00 — 0 commitsThu 1:00 — 0 commitsThu 2:00 — 0 commitsThu 3:00 — 0 commitsThu 4:00 — 0 commitsThu 5:00 — 0 commitsThu 6:00 — 0 commitsThu 7:00 — 0 commitsThu 8:00 — 1 commitsThu 9:00 — 1 commitsThu 10:00 — 1 commitsThu 11:00 — 3 commitsThu 12:00 — 2 commitsThu 13:00 — 8 commitsThu 14:00 — 5 commitsThu 15:00 — 16 commitsThu 16:00 — 10 commitsThu 17:00 — 4 commitsThu 18:00 — 0 commitsThu 19:00 — 0 commitsThu 20:00 — 0 commitsThu 21:00 — 3 commitsThu 22:00 — 0 commitsThu 23:00 — 0 commitsFri 0:00 — 1 commitsFri 1:00 — 0 commitsFri 2:00 — 0 commitsFri 3:00 — 0 commitsFri 4:00 — 0 commitsFri 5:00 — 0 commitsFri 6:00 — 0 commitsFri 7:00 — 0 commitsFri 8:00 — 2 commitsFri 9:00 — 3 commitsFri 10:00 — 1 commitsFri 11:00 — 5 commitsFri 12:00 — 6 commitsFri 13:00 — 4 commitsFri 14:00 — 21 commitsFri 15:00 — 5 commitsFri 16:00 — 7 commitsFri 17:00 — 17 commitsFri 18:00 — 5 commitsFri 19:00 — 2 commitsFri 20:00 — 3 commitsFri 21:00 — 1 commitsFri 22:00 — 1 commitsFri 23:00 — 0 commitsSat 0:00 — 0 commitsSat 1:00 — 0 commitsSat 2:00 — 0 commitsSat 3:00 — 0 commitsSat 4:00 — 0 commitsSat 5:00 — 0 commitsSat 6:00 — 0 commitsSat 7:00 — 0 commitsSat 8:00 — 0 commitsSat 9:00 — 0 commitsSat 10:00 — 0 commitsSat 11:00 — 2 commitsSat 12:00 — 1 commitsSat 13:00 — 1 commitsSat 14:00 — 0 commitsSat 15:00 — 0 commitsSat 16:00 — 1 commitsSat 17:00 — 0 commitsSat 18:00 — 3 commitsSat 19:00 — 1 commitsSat 20:00 — 2 commitsSat 21:00 — 0 commitsSat 22:00 — 1 commitsSat 23:00 — 2 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.
DateListRankStars gained
Apr 25, 2026daily#11+220
Apr 24, 2026daily#4+267
Apr 23, 2026daily#5+164