ML Intern Interactive Mode vs Headless Mode: Complete Execution Guide
ML Intern's interactive mode provides a rich CLI with animated output and manual tool approvals, while headless mode runs single prompts programmatically with auto-approvals and instant, static output designed for automation.
ML Intern, an open-source agent framework in the huggingface/ml-intern repository, supports two distinct execution pathways through its unified entry point in agent/main.py. Understanding the difference between interactive mode and headless mode execution is essential for choosing the right approach for human-in-the-loop experimentation versus automated pipelines.
Entry Point Architecture: main() vs headless_main()
In agent/main.py, the repository defines two primary async entry functions that determine execution behavior. The interactive mode invokes async def main() (lines 809-828), which initializes a persistent REPL loop using PromptSession for line-by-line input. This function displays a startup banner, accepts /commands (such as /help or /yolo), and maintains state across multiple turns.
Conversely, headless mode triggers async def headless_main(prompt, ...) (lines 1029-1060), accepting a prompt string as an argument and executing a single iteration before terminating. This function activates when passing a quoted string to the module: python -m agent.main "your prompt".
Display and Terminal Rendering Differences
The visual output differs significantly between modes. Interactive mode employs a rich typewriter animation implemented in agent/utils/terminal_display.py (lines 372-380), printing markdown character-by-character with a shimmering "Thinking..." indicator that requires TTY cursor control.
Headless mode bypasses animation entirely, setting instant=True to dump fully rendered markdown immediately (lines 372-376). This append-only output avoids cursor manipulation, making it suitable for log capture, pipe redirection, and non-terminal environments like CI pipelines or Jupyter notebooks.
Tool Call Approval and Automation Behavior
User approval workflows represent a critical functional divergence. In interactive mode, the REPL pauses when tools require confirmation, prompting the user unless the /yolo command has enabled auto-approval.
Headless mode automatically enables config.yolo_mode = True (defined in agent/config.py, lines 29-30), bypassing all confirmation prompts. According to the source code in agent/main.py (lines 1049-1055), the system automatically answers "approval_required" events, allowing tool chains to execute uninterrupted—essential for batch processing and API integrations.
Concurrency and Sub-Agent Handling
Sub-agent execution demonstrates architectural differences in display handling. Interactive mode uses live cursor-movement tricks to render updating "research" overlays from sub-agents in real-time.
In headless mode, research outputs are buffered and emitted as static blocks upon completion (lines 1039-1065), eliminating the need for terminal cursor control that would break in headless environments.
Running ML Intern: Practical Examples
Interactive Session
python -m agent.main
This launches the REPL with banner display, slash-command support, and animated response rendering. Use Ctrl-C twice to exit gracefully.
Headless CLI Execution
python -m agent.main "find me bird datasets"
Loads the HF token, enables auto-approval via yolo_mode, streams instant output, and exits automatically upon completion.
Programmatic Headless API
import asyncio
from agent.main import headless_main
async def run():
await headless_main(
prompt="summarize the latest Hugging Face blog post",
model="gpt-4o-mini",
max_iterations=5,
stream=False # Set True to receive incremental chunks
)
asyncio.run(run())
Both modes share the core submission logic in agent/core/agent_loop.py (lines 54-62), ensuring consistent agent behavior regardless of interface.
Summary
- Entry Functions: Interactive uses
main()for REPL loops; headless usesheadless_main()for single execution - Visual Output: Interactive shows animated typewriter effects; headless uses instant static rendering with
instant=True - Tool Approvals: Interactive prompts for confirmation; headless auto-approves all tools via
config.yolo_mode = True - Sub-Agent Display: Interactive updates live with cursor tricks; headless buffers and prints static blocks
- Use Cases: Interactive suits experimentation and debugging; headless serves automation, CI/CD, and API integration
- Shutdown: Interactive handles
Ctrl-Cgracefully with cancellation; headless exits automatically on completion
Frequently Asked Questions
Can I switch from interactive to headless mode without restarting ML Intern?
No, the execution mode is determined at startup by whether you invoke python -m agent.main without arguments (interactive) or with a prompt string (headless). The headless_main() and main() functions represent distinct entry points in agent/main.py with different initialization logic, so you must restart the process to switch modes.
Does headless mode support streaming output?
Yes, when using the programmatic API, set stream=True in the headless_main() call to receive incremental chunks. However, unlike interactive mode's character-by-character typewriter effect, headless streaming outputs raw markdown without cursor animation, making it safe for pipe redirection and log files.
Why do tool calls auto-approve in headless mode but not interactive mode?
Headless execution sets config.yolo_mode = True automatically according to agent/main.py (lines 1049-1055) because there is no TTY attached for user input. This prevents the agent from hanging indefinitely waiting for approval signals that cannot arrive in automated environments like Kubernetes pods or GitHub Actions runners.
Can I use slash commands like /yolo in headless mode?
No, slash commands such as /yolo, /help, and /reset are features of the interactive PromptSession REPL implemented in main(). Headless mode accepts configuration only through function arguments and CLI flags, not through command intermediates, as it lacks the persistent input loop required to process such commands.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →