Skip to main content

Reference AAEP subscriber that prints event streams to the terminal in a readable format

Project description

CLI Debug Subscriber

A reference AAEP subscriber that connects to any producer's /events SSE endpoint and prints the event stream in a screen-reader-friendly terminal format. Useful for debugging, demos, and as a starting point for your own subscriber.

If you're new to AAEP and want to see what events look like in practice, this is the easiest way.


What this subscriber does

  • Connects to any AAEP producer's /events SSE endpoint
  • Parses each event and prints it in a clear human-readable format
  • Handles all 12 core event types
  • Replies to awaiting.confirmation and awaiting.clarification events interactively
  • Color-codes critical-urgency events when the terminal supports it
  • Validates each received event against the AAEP schemas (optional, via --validate)
  • Saves the captured stream to a JSONL file (optional, via --save)

This subscriber is the simplest possible AAEP consumer. It demonstrates the protocol's value without any AT integration — you can run it against any producer and observe how the protocol surfaces information to users.


Installation

cd examples/subscribers/cli-debug
pip install -e .

Requires Python 3.10 or newer.


Quick start

In one terminal, start any AAEP producer (e.g., the python-minimal example):

python -m aaep_minimal_producer.server --port 8080

In another terminal, run this subscriber:

aaep-listen --endpoint http://localhost:8080

In a third terminal, send a request to the producer:

curl -X POST http://localhost:8080/sessions \
    -H "Content-Type: application/json" \
    -d '{"user_message": "What is my balance?"}'

You should see events stream into the subscriber's terminal in real time, including state changes, tool invocations, streaming output, and the session completion event.

For the confirmation flow, try:

curl -X POST http://localhost:8080/sessions \
    -H "Content-Type: application/json" \
    -d '{"user_message": "Send an email to alice@example.com"}'

The subscriber will display the confirmation prompt and ask you (in the terminal) to accept or reject. Your decision is sent back to the producer via POST /messages.


Usage

aaep-listen --endpoint URL [OPTIONS]

Required:
    --endpoint URL          Producer base URL (e.g., http://localhost:8080)

Optional:
    --save FILE             Also save events to this JSONL file
    --validate              Validate each event against AAEP schemas
    --filter-urgency LEVEL  Only display events with this urgency (normal|critical)
    --filter-type TYPE      Only display events of this type (repeatable)
    --auto-reject           Auto-reject all confirmations (for unattended use)
    --auto-accept           Auto-accept all confirmations (DANGEROUS, debug only)
    --no-color              Disable terminal colors
    --quiet                 Print events as compact one-line JSON only
    --help                  Show this help
    --version               Show version

Sample output

[12:34:56.789] aaep:agent.session.started        Processing: What is my balance?
[12:34:56.823] aaep:agent.state.changed          Considering the request.
                  from_state: idle -> to_state: thinking
[12:34:57.105] aaep:agent.tool.invoked           Calling fetch_balance.
                  tool: fetch_balance
                  risk_level: low
                  irreversible: false
[12:34:57.401] aaep:agent.tool.completed         $3,247.18
                  tool: fetch_balance
                  status: success
[12:34:57.452] aaep:agent.state.changed          Generating response.
                  from_state: calling_tool -> to_state: writing_output
[12:34:57.501] aaep:agent.output.streaming       Your balance is $3,247.18.
                  position: 0  complete: false
[12:34:57.612] aaep:agent.output.streaming       Anything else?
                  position: 27  complete: true
[12:34:57.701] aaep:agent.session.completed      Response complete.
                  duration_ms: 912
                  tool_invocations_count: 1

Critical-urgency events appear in red (or with !! prefix if --no-color).


Confirmation flow

When the producer emits an awaiting.confirmation event, the subscriber pauses and prompts:

!! [12:34:57.300] aaep:agent.awaiting.confirmation    Confirm: call send_email?
                    action: Call send_email with: to=alice@example.com, subject=Hello
                    consequence: This action cannot be easily undone.
                    risk_level: high
                    irreversible: true
                    default_decision: reject
                    timeout: 300 seconds

Accept this action? [y/N/?]:
  • y or yes → accept (sends decision: "accept")
  • n or no or just Enter → reject (sends decision: "reject")
  • ? → show the full event JSON

The default is reject, matching the protocol's safe-by-default contract for irreversible high-risk actions.


Using as a debugging tool

Common debug recipes:

# Save everything from a session for later inspection
aaep-listen --endpoint http://localhost:8080 --save session.jsonl

# Only see critical events
aaep-listen --endpoint http://localhost:8080 --filter-urgency critical

# Validate every event against schemas (catches malformed producers)
aaep-listen --endpoint http://localhost:8080 --validate

# Capture without prompting in CI
aaep-listen --endpoint http://localhost:8080 --auto-reject --save run.jsonl

# Compact JSON output for piping into jq or other tools
aaep-listen --endpoint http://localhost:8080 --quiet | jq 'select(.urgency == "critical")'

Using as the basis for your own subscriber

This subscriber's source (aaep_cli_debug/listener.py) is structured as a starting point for real subscribers:

  • The SSE consumer is in aaep_cli_debug/listener.py:listen()
  • The event-to-text rendering is in aaep_cli_debug/listener.py:format_event()
  • The reply mechanism is in aaep_cli_debug/listener.py:send_reply()

To build an AT-integrated subscriber, replace format_event() with calls to your AT's speech engine, and send_reply() with your AT's user-input mechanism. The transport layer (SSE consumption, reply posting) doesn't change.

See ../nvda-addon-prototype/ for a worked example of replacing the rendering layer with an NVDA speech-engine integration.


Project layout

cli-debug/
├── README.md
├── pyproject.toml
├── aaep_cli_debug/
│   ├── __init__.py
│   └── listener.py        # SSE consumer + event formatter + reply sender
└── tests/
    └── test_listener.py

See also

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

aaep_cli_debug-1.0.0.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

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

aaep_cli_debug-1.0.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file aaep_cli_debug-1.0.0.tar.gz.

File metadata

  • Download URL: aaep_cli_debug-1.0.0.tar.gz
  • Upload date:
  • Size: 13.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for aaep_cli_debug-1.0.0.tar.gz
Algorithm Hash digest
SHA256 e4b491a60aa1f2c8816553668df63fea90ddadd1b9198db2bc8ba48c7b87aa19
MD5 6ed9aeeb9ea20a812858774d4e5d511a
BLAKE2b-256 e93d1b0adec5b29074cf644265d9c8b8a10c23923c0d028f9d3a611e7241a37f

See more details on using hashes here.

File details

Details for the file aaep_cli_debug-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: aaep_cli_debug-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for aaep_cli_debug-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 01447e56268d6c654777c5e882c2fc5cca573a589fd947007a6d66b1a30c88e2
MD5 0afe702281780c9e34e20262fbf7c81d
BLAKE2b-256 115dc9f9be7a8a46438a95cea8cef27845053553c76d8f48659496107d54a84d

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