huggingface/ml-internPublicArchived

Archived — ML Intern is no longer maintained. Continue with HuggingChat.

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

Stars
10.8K
+-5 today
Forks
1.2K
Watchers
48
Open issues
0
Open PRs
0
Contributors
~17
Commits
493
Branches
57

PythonApache-2.0Created Oct 30, 2025Last push 4d ago+-9 stars this week+50 this month

Quick answers

What is ml-intern?
A terminal-based AI agent configured for machine learning operations using Hugging Face endpoints and local models.
What does ml-intern do?
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.
Who is ml-intern for?
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.
How do I get started with ml-intern?
ml-intern --model moonshotai/Kimi-K2.7-Code:novita "your prompt"
How popular is ml-intern on GitHub?
huggingface/ml-intern has 10,812 stars and 1,191 forks on GitHub, and gained -9 stars in the last 7 days.
What license does ml-intern use?
huggingface/ml-intern is released under the Apache-2.0 license.

Star history

since Jul 29, 2026
05K10KJul 2026Aug 2026Sep 2026Oct 2026
10.8K stars as of Oct 2, 2026. Measured daily since Jul 29, 2026; GitHub no longer exposes earlier star timestamps.

Contribution activity

commits per day, last 52 weeks
OctNovDecJanFebMarAprMayJunJulAugSepMonWedFri2025-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 commits2026-08-09: 0 commits2026-08-10: 0 commits2026-08-11: 0 commits2026-08-12: 0 commits2026-08-13: 0 commits2026-08-14: 0 commits2026-08-15: 0 commits2026-08-16: 0 commits2026-08-17: 0 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 0 commits2026-08-22: 0 commits2026-08-23: 0 commits2026-08-24: 0 commits2026-08-25: 0 commits2026-08-26: 0 commits2026-08-27: 0 commits2026-08-28: 0 commits2026-08-29: 0 commits2026-08-30: 0 commits2026-08-31: 0 commits2026-09-01: 0 commits2026-09-02: 0 commits2026-09-03: 0 commits2026-09-04: 0 commits2026-09-05: 0 commits2026-09-06: 0 commits2026-09-07: 0 commits2026-09-08: 0 commits2026-09-09: 1 commit2026-09-10: 0 commits2026-09-11: 0 commits2026-09-12: 0 commits2026-09-13: 0 commits2026-09-14: 2 commits2026-09-15: 0 commits2026-09-16: 0 commits2026-09-17: 0 commits2026-09-18: 0 commits2026-09-19: 0 commits2026-09-20: 0 commits2026-09-21: 0 commits2026-09-22: 0 commits2026-09-23: 0 commits2026-09-24: 0 commits2026-09-25: 0 commits2026-09-26: 0 commits2026-09-27: 0 commits2026-09-28: 0 commits2026-09-29: 0 commits2026-09-30: 0 commits2026-10-01: 0 commits2026-10-02: 0 commits2026-10-03: 0 commits
457 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Widely adopted

    10,812 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

Important

ML Intern is no longer maintained. Both the hosted web application and the ml-intern CLI have been retired. Continue with HuggingChat.

This repository is retained for historical reference only. No support, bug fixes, or security updates will be provided.

ML Intern (retired)

smolagents logo

License Status: retired

Historical documentation (unsupported)

The documentation below is preserved for historical reference. The project is no longer supported or maintained.

ML Intern was an agent that autonomously researched, wrote, and shipped ML-related code using the Hugging Face ecosystem, with deep access to documentation, 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

Code frequency

additions and deletions
+32.6K-32.6KWeek of 2025-10-26: +3,674 linesWeek of 2025-10-26: -345 linesWeek of 2025-11-02: +0 linesWeek of 2025-11-02: -0 linesWeek of 2025-11-09: +2,849 linesWeek of 2025-11-09: -530 linesWeek of 2025-11-16: +1,114 linesWeek of 2025-11-16: -739 linesWeek of 2025-11-23: +2,931 linesWeek of 2025-11-23: -969 linesWeek of 2025-11-30: +0 linesWeek of 2025-11-30: -0 linesWeek of 2025-12-07: +774 linesWeek of 2025-12-07: -11 linesWeek of 2025-12-14: +1,088 linesWeek of 2025-12-14: -308 linesWeek of 2025-12-21: +3,793 linesWeek of 2025-12-21: -1,672 linesWeek of 2025-12-28: +4,909 linesWeek of 2025-12-28: -2,586 linesWeek of 2026-01-04: +6,731 linesWeek of 2026-01-04: -4,067 linesWeek of 2026-01-11: +32,629 linesWeek of 2026-01-11: -23,260 linesWeek of 2026-01-18: +1,282 linesWeek of 2026-01-18: -567 linesWeek of 2026-01-25: +1,068 linesWeek of 2026-01-25: -671 linesWeek of 2026-02-01: +1 linesWeek of 2026-02-01: -1 linesWeek of 2026-02-08: +974 linesWeek of 2026-02-08: -4 linesWeek of 2026-02-15: +0 linesWeek of 2026-02-15: -0 linesWeek of 2026-02-22: +9,411 linesWeek of 2026-02-22: -5,055 linesWeek of 2026-03-01: +981 linesWeek of 2026-03-01: -459 linesWeek of 2026-03-08: +1,374 linesWeek of 2026-03-08: -1,268 linesWeek of 2026-03-15: +66 linesWeek of 2026-03-15: -29 linesWeek of 2026-03-22: +1,389 linesWeek of 2026-03-22: -625 linesWeek of 2026-03-29: +2,997 linesWeek of 2026-03-29: -1,215 linesWeek of 2026-04-05: +4,064 linesWeek of 2026-04-05: -4,580 linesWeek of 2026-04-12: +341 linesWeek of 2026-04-12: -1,862 linesWeek of 2026-04-19: +7,209 linesWeek of 2026-04-19: -990 linesWeek of 2026-04-26: +12,758 linesWeek of 2026-04-26: -2,065 linesWeek of 2026-05-03: +10,356 linesWeek of 2026-05-03: -1,698 linesWeek of 2026-05-10: +2,551 linesWeek of 2026-05-10: -86 linesWeek of 2026-05-17: +0 linesWeek of 2026-05-17: -0 linesWeek of 2026-05-24: +0 linesWeek of 2026-05-24: -0 linesWeek of 2026-05-31: +4,134 linesWeek of 2026-05-31: -3,650 linesWeek of 2026-06-07: +8,847 linesWeek of 2026-06-07: -2,048 linesWeek of 2026-06-14: +930 linesWeek of 2026-06-14: -270 linesWeek of 2026-06-21: +0 linesWeek of 2026-06-21: -0 linesWeek of 2026-06-28: +0 linesWeek of 2026-06-28: -0 linesWeek of 2026-07-05: +0 linesWeek of 2026-07-05: -0 linesWeek of 2026-07-12: +0 linesWeek of 2026-07-12: -0 linesWeek of 2026-07-19: +0 linesWeek of 2026-07-19: -0 linesWeek of 2026-07-26: +0 linesWeek of 2026-07-26: -0 linesWeek of 2026-08-02: +0 linesWeek of 2026-08-02: -0 linesWeek of 2026-08-09: +0 linesWeek of 2026-08-09: -0 linesWeek of 2026-08-16: +0 linesWeek of 2026-08-16: -0 linesWeek of 2026-08-23: +0 linesWeek of 2026-08-23: -0 linesWeek of 2026-08-30: +0 linesWeek of 2026-08-30: -0 linesWeek of 2026-09-06: +2 linesWeek of 2026-09-06: -0 linesWeek of 2026-09-13: +0 linesWeek of 2026-09-13: -0 linesOct 26, 2025Sep 13, 2026
+131.2K lines added, -61.6K removed over the last year.

Commits per week

last 52 weeks
420Week 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 commitsWeek of 2026-08-09: 0 commitsWeek of 2026-08-16: 0 commitsWeek of 2026-08-23: 0 commitsWeek of 2026-08-30: 0 commitsWeek of 2026-09-06: 1 commitsWeek of 2026-09-13: 2 commitsWeek of 2026-09-20: 0 commitsWeek of 2026-09-27: 0 commitsOct 5, 2025Sep 27, 2026
457 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 — 4 commitsMon 10:00 — 7 commitsMon 11:00 — 6 commitsMon 12:00 — 5 commitsMon 13:00 — 3 commitsMon 14:00 — 12 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 — 1 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