How to Set the Default Ponytail Mode for New Sessions Using Environment Variables

Set the PONYTAIL_DEFAULT_MODE environment variable to one of the valid modes (off, lite, full, ultra, or review) before launching your session, and Ponytail will automatically use that value as the default operating mode for all new contexts.

The DietrichGebert/ponytail repository provides a hierarchical configuration system that determines how much skill context is injected into LLM prompts. By setting an environment variable, you can globally control this behavior without modifying source code or passing arguments to every function call.

Understanding Ponytail's Configuration Hierarchy

Ponytail resolves the active mode through a strict precedence chain implemented in ponytail/main/__init__.py:

  1. Explicit argument – The mode parameter passed directly to build_injected_context(mode)
  2. Environment variable – The value of PONYTAIL_DEFAULT_MODE
  3. Configuration file – The defaultMode key in a JSON config file
  4. Built-in fallback – The constant DEFAULT_MODE = "full" (defined at line 11)

The environment variable serves as the primary mechanism for establishing persistent defaults across sessions, sitting just below explicit runtime overrides.

Setting the PONYTAIL_DEFAULT_MODE Environment Variable

Configure the variable in your shell or CI/CD environment before invoking any Ponytail commands.

Linux and macOS (Bash/Zsh)

Set the variable for your entire session:

export PONYTAIL_DEFAULT_MODE=lite
ponytail run your_script.py

Set it for a single command execution:

PONYTAIL_DEFAULT_MODE=ultra ponytail run your_script.py

Windows PowerShell

$env:PONYTAIL_DEFAULT_MODE = "full"
ponytail run your_script.py

Windows Command Prompt (CMD)

set PONYTAIL_DEFAULT_MODE=lite
ponytail run your_script.py

How Ponytail Processes the Environment Variable

During session initialization, the _default_mode() function in ponytail/main/__init__.py retrieves and validates the environment variable. The code explicitly reads:

env_mode = _normalize_config_mode(os.environ.get("PONYTAIL_DEFAULT_MODE"))

The normalization logic (around line 40) handles validation through the _normalize_config_mode() function:

def _normalize_config_mode(mode: str | None) -> str | None:
    if not isinstance(mode, str):
        return None
    mode = mode.strip().lower()
    return mode if mode in CONFIG_MODES else None

This ensures the value is case-insensitive and whitespace-tolerant. If the normalized string exists in CONFIG_MODES, it becomes the effective mode for the session; otherwise, Ponytail proceeds to check the configuration file or falls back to "full".

Valid Mode Values

The PONYTAIL_DEFAULT_MODE environment variable accepts the following string values:

  • off – Disables context injection entirely
  • lite – Enables minimal context for reduced latency
  • full – Standard context level (built-in fallback default)
  • ultra – Maximum context injection for complex tasks
  • review – Specialized mode for code review contexts

The validation set CONFIG_MODES contains these options, allowing the _normalize_config_mode() filter to accept any case variation (e.g., LITE, Lite, and lite are equivalent).

Overriding the Default Mode at Runtime

Even with PONYTAIL_DEFAULT_MODE configured in your environment, you can force a specific mode for individual calls by passing the mode argument to build_injected_context():

from ponytail import build_injected_context

# Explicitly forces 'ultra' mode, bypassing the environment variable

ctx = build_injected_context(mode="ultra")

This explicit parameter takes precedence over all other configuration sources, including the environment variable and configuration files.

Cross-Platform JavaScript Support

For browser or Node.js runtimes, Ponytail reads the same environment variable through ponytail/main/hooks/ponytail-config.js. This ensures consistent behavior between Python backends and JavaScript frontends when the variable is set at the system level.

Summary

  • Set PONYTAIL_DEFAULT_MODE to off, lite, full, ultra, or review to control default session behavior
  • Precedence order: Explicit argument → Environment variable → Config file → "full" fallback
  • Implementation: Core logic resides in ponytail/main/__init__.py via _default_mode() and _normalize_config_mode()
  • Case handling: Values are normalized with .strip().lower(), making them case-insensitive
  • Override: Use build_injected_context(mode="...") to bypass the environment default for specific calls

Frequently Asked Questions

What happens if I don't set the PONYTAIL_DEFAULT_MODE environment variable?

If the environment variable is undefined, empty, or contains an invalid value, Ponytail proceeds to check the configuration file for a defaultMode key. If that is also absent, it falls back to the built-in constant DEFAULT_MODE = "full" defined in ponytail/main/__init__.py.

Is the environment variable case-sensitive?

No. The _normalize_config_mode() function in ponytail/main/__init__.py explicitly converts the input to lowercase using .lower() and trims whitespace with .strip(). Therefore, FULL, Full, and full are all treated identically.

Can I set the default mode in a configuration file instead of using environment variables?

Yes. Ponytail supports JSON configuration files where you can specify a "defaultMode" key. However, the configuration hierarchy places environment variables above file settings, meaning PONYTAIL_DEFAULT_MODE will override any value defined in the configuration file if both are present.

How do I verify which mode is currently active?

You can programmatically inspect the resolved mode by calling _default_mode() after importing from the package:

import os
from ponytail import _default_mode

os.environ["PONYTAIL_DEFAULT_MODE"] = "lite"
print(_default_mode())  # Output: lite

Additionally, Ponyltail injects a banner into the generated context (via _fallback_instructions()) that indicates the active mode level, making it visible in the final prompt passed to the LLM.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →