How Ponytail Activates on Session Start: Hermes Plugin Lifecycle Explained
Ponytail automatically activates when the register() function binds a pre-LLM hook to the Hermes context, injecting instructional context into the first model request of every session.
Ponytail is a Hermes plugin that enhances LLM-agent interactions by automatically prepending contextual instructions at the start of each conversation. Understanding how Ponytail activates on session start requires examining its registration mechanism and hook architecture in the DietrichGebert/ponytail repository. When properly initialized, the plugin intercepts the first LLM call to insert mode-specific guidance without requiring manual intervention.
The Activation Process on Session Start
The activation sequence begins when ponytail.register(ctx) is invoked with a valid Hermes context object. According to the source code in __init__.py (lines 95-106), this function registers three critical components with the Hermes framework:
- A pre-LLM-call hook (
_pre_llm_call) viactx.register_hook("pre_llm_call", _pre_llm_call) - A gateway-dispatch rewrite hook (
rewrite_gateway_command) viactx.register_hook("pre_gateway_dispatch", rewrite_gateway_command) - Slash commands including
/ponytail,/ponytail-review, and others for runtime configuration
Hook Execution and Context Injection
As soon as a session issues its first LLM request, Hermes invokes every registered pre_llm_call hook. Ponytail’s _pre_llm_call handler executes build_injected_context (implemented in __init__.py, lines 25-33 and 105-112) to construct the mode-filtered instructional text.
The hook returns a dictionary in the format { "context": <text> }, which Hermes automatically injects as a prefix to the model’s prompt. This injection happens transparently before the LLM processes the user's actual query.
Mode Resolution Hierarchy
The content injected on session start depends on the active mode, resolved in the following priority order:
- Explicit argument passed directly to
build_injected_context - Environment variable
PONYTAIL_DEFAULT_MODE(normalized via_normalize_config_mode) - Configuration file at
~/.config/ponytail/config.json(if present) - Hard-coded fallback
DEFAULT_MODE = "full"
When no other configuration exists, the first LLM call receives a prefix such as:
PONYTAIL MODE ACTIVE — level: full
<filtered skill description …>
Subsequent calls in the same session reuse this context unless the user changes modes via slash commands.
Practical Implementation Examples
Registering Ponytail with a Hermes Instance
from hermes import Hermes
import ponytail
# Create a Hermes context (or obtain one from your app)
ctx = Hermes()
# Wire Ponytail into the session
ponytail.register(ctx)
# From now on every new session will receive Ponytail’s injected context
# on the very first LLM call.
Changing the Mode During a Session
# User enters the slash command in the chat UI
# /ponytail lite
# Hermes routes the command to Ponytail’s `_handle_mode_command`,
# which updates the global `_current_mode`.
# The next LLM turn will see:
# PONYTAIL MODE ACTIVE — level: lite
Examining the Injected Context
from ponytail import build_injected_context
# Assuming default mode (full)
print(build_injected_context())
# =>
# PONYTAIL MODE ACTIVE — level: full
#
# <skill body filtered for “full” mode>
Key Source Files
Understanding Ponytail's activation mechanism requires familiarity with these components:
__init__.py: Core plugin implementation containing mode handling, context building, and hook registration logicskills/ponytail/SKILL.md: Full-mode skill description injected during activationskills/ponytail-review/SKILL.md: Alternative skill content for "review" mode (activated viaPONYTAIL_DEFAULT_MODE=review)README.md: Repository overview and initialization instructions
Summary
- Ponytail activates on session start by registering a
pre_llm_callhook throughponytail.register(ctx)that intercepts the first LLM request - The hook builds mode-filtered context via
build_injected_context(lines 25-33 and 105-112 in__init__.py) and returns it in a dictionary format for Hermes injection - Mode selection follows a strict hierarchy: explicit argument, environment variable
PONYTAIL_DEFAULT_MODE, config file at~/.config/ponytail/config.json, then falls back toDEFAULT_MODE = "full" - Slash commands like
/ponytailallow runtime mode changes that affect subsequent LLM turns by updating the global_current_modevariable - The registration logic resides in
__init__.py(lines 95-106), which binds the plugin to the Hermes lifecycle
Frequently Asked Questions
What triggers Ponytail to start working in a new session?
Ponytail activates when Hermes invokes the registered _pre_llm_call hook during the first LLM request of a session. This hook, registered via ctx.register_hook("pre_llm_call", _pre_llm_call) in __init__.py (lines 95-106), executes automatically without requiring manual activation commands, ensuring the context is injected before the model processes any user input.
How do I configure Ponytail to use a specific mode on startup?
Set the environment variable PONYTAIL_DEFAULT_MODE to your preferred mode (e.g., full or review) before starting the session, or create a JSON config file at ~/.config/ponytail/config.json specifying the default mode. If neither exists, Ponytail defaults to DEFAULT_MODE = "full" as defined in the source code and processed by the _normalize_config_mode function.
Can I change Ponytail's behavior after a session has started?
Yes. Users can issue slash commands such as /ponytail lite or /ponytail review during an active session. Hermes routes these commands to _handle_mode_command, which updates the global _current_mode variable, causing subsequent LLM calls to receive the newly configured context prefix.
Where does the injected context text come from?
The injected content originates from skill definition files located in the skills/ directory. For full mode, Ponytail loads skills/ponytail/SKILL.md. For review mode, it loads skills/ponytail-review/SKILL.md. The build_injected_context function filters these files based on the current mode before injection into the LLM prompt.
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 →