Skip to main content

Token-optimized Ansible output for AI coding agents

Project description

ansible-agent-callback

codecov

Token-optimized Ansible stdout callback plugin for AI coding agents. Reduces output by 70-90% compared to the default callback.

Compression is asymmetric on purpose:

  • Success path: aggressive — clean runs collapse to a single RECAP line; ok and skipped tasks produce zero output.
  • Failure path: readable — full stack traces stay intact via msg> / stderr> continuation lines, plus rc, and full per-task detail captured to a companion file on demand. Still smaller than default, but optimized for diagnosis over byte count.

Verified on a mixed-shape fixture (12 ok, 3 changed, 3 skipped, 2 ignored failures, 1 loop) — see bench/ and run make bench to reproduce:

Metric default agent Reduction
bytes 3,174 499 84.3%
lines 90 15 83.3%
words 286 79 72.4%

Clean runs (zero changes, zero failures) collapse to a single line regardless of task count, so the reduction approaches the default's total volume the larger your playbook.

Getting Started

Install the plugin and configure your AI coding agents in one command:

uvx ansible-agent-callback install

This will:

  1. Copy the callback plugin to ~/.ansible/plugins/callback/
  2. Detect which AI coding agents you have installed
  3. Let you pick which ones to configure (detected agents are pre-selected)

To skip the interactive selector and configure everything automatically:

uvx ansible-agent-callback install --all

That's it. Your agents will now use the token-optimized output when running Ansible.

Output Format

Only changed, failed, and unreachable results are shown. Ok and skipped tasks produce zero output. A fully successful playbook run outputs just the RECAP line.

PLAY | Configure webservers
TASK | Configure nginx
changed | web01 | diff: +worker_processes 4;
failed | db01 | msg: Permission denied | rc: 1
RECAP | web01: ok=3 changed=1 | db01: ok=1 failed=1

Diff summaries

For changed tasks with diff data, the plugin shows the first non-comment change line. Comment-only changes (# or ; prefix) are skipped so the agent isn't misled by -# old comment while the real edit is buried below. Multi-line diffs append (+N -M) totals to signal there's more context:

changed | web01 | diff: -workers 2
changed | web02 | diff: +listen 443 (+3 -1)

Failures with multi-line output

Stack traces stay readable. The lead failed line carries a single-line summary plus rc; remaining content emits as continuation lines prefixed with msg> or stderr> :

failed | db01 | stderr: Traceback (most recent call last): | rc: 1
stderr>   File "/opt/app/run.py", line 5, in <module>
stderr>     do_thing()
stderr> RuntimeError: oops

The prefix is unambiguous (real output never produces it) and grep-friendly: ^failed finds every failure, and an agent reads forward until the next non-continuation line for the full block.

Full Output When Things Fail

The compressed format keeps successful runs token-cheap, but agents sometimes need the full picture to diagnose a failure. Set ANSIBLE_LOG_PATH and the plugin captures the complete, untrimmed result of every failed or unreachable task:

ANSIBLE_LOG_PATH=/tmp/ansible.log ansible-playbook site.yml

Full detail goes to a companion file beside the log, <ANSIBLE_LOG_PATH>.details.jsonl, and a LOG line after the RECAP points at it:

failed | db01 | msg: Permission denied | rc: 1
RECAP | db01: ok=1 failed=1
LOG | /tmp/ansible.log.details.jsonl

Each line is one JSON object with the host, task, status, and the full result (rc, cmd, stderr, stdout, msg, diff, ...), everything an agent needs without re-running the play. The module invocation and internal keys are dropped, and no_log results stay censored by Ansible. The file is written only when something fails and cleared at the start of each run, so a clean run leaves no file and stdout stays token-cheap.

Why a companion file and not ANSIBLE_LOG_PATH itself? That log is fed by Ansible's Display, which records whatever the active stdout callback prints. With this callback that means the same compressed lines, not the full result, so the untrimmed detail needs its own file.

When a run fails and ANSIBLE_LOG_PATH is not set, the plugin appends a single HINT after the RECAP so an agent can opt in:

RECAP | db01: ok=1 failed=1
HINT | set ANSIBLE_LOG_PATH=<path> and re-run to capture full failure detail

Clean runs stay clean: no hint, no file, no extra lines.

Commands

ansible-agent-callback install              # Install plugin + configure agents
ansible-agent-callback install --all        # Auto-configure detected agents
ansible-agent-callback install --agents claude-code,codex-cli
ansible-agent-callback install --plugin-only # Just the plugin, no agent config
ansible-agent-callback update               # Update plugin to latest version
ansible-agent-callback uninstall            # Remove plugin + agent configs
ansible-agent-callback env                  # Print export for other agents

Supported Agents

Agent Config
Claude Code ~/.claude/settings.json
Codex CLI ~/.codex/config.toml
Gemini CLI ~/.gemini/.env
Shell profile ~/.zshrc or ~/.bashrc
Ansible global ~/.ansible.cfg

Development

make dev    # Install in editable mode
make test   # Run tests
make bench  # Compare default vs agent callback output volume
make build  # Build package

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ansible_agent_callback-0.3.2.tar.gz (23.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ansible_agent_callback-0.3.2-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

Details for the file ansible_agent_callback-0.3.2.tar.gz.

File metadata

  • Download URL: ansible_agent_callback-0.3.2.tar.gz
  • Upload date:
  • Size: 23.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ansible_agent_callback-0.3.2.tar.gz
Algorithm Hash digest
SHA256 8db13259b6c8403df90554fa49602ed429ca79b0fc1f81903cd65440a7259a17
MD5 85c5844964949ded6c3ca9ece0df14c2
BLAKE2b-256 4104e513c5ffcc25cdc6ef1e5a867154d852c287b35e8f64cb8b768513c63562

See more details on using hashes here.

File details

Details for the file ansible_agent_callback-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: ansible_agent_callback-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for ansible_agent_callback-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8262b2974d1f3ba9449fd2ce31f0b8d18e3a790e83062f571bd5ef7b8e1f5458
MD5 943949f4368c75219248b956756bf35d
BLAKE2b-256 3a544fe343985b214090d7798394508878d72bb13c226b7c9d593ed356f2cc6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page