Skip to main content

Local agent status reference implementation

Project description

agent-status

agent-status is a generic local agent status standard with a small reference CLI. Core file format and validation logic stay lean. Display commands list and watch require rich; non-display commands like emit, get, validate, and prune work without it.

Why a local status layer exists

Remote protocols answer remote questions. Local operators still need fast answers to a different set of questions: which agents are running here, what are they doing, and is the latest snapshot stale?

Why this needs its own standard:

  • A2A is designed for remote discovery and task interaction, not workstation-local runtime visibility.
  • Local operators need data that A2A does not model directly, such as process lifecycle, PID, workspace, and heartbeat freshness.
  • One file per agent instance enables simple tooling: shell scripts, CLIs, watchers, and validators can all read the same shape.
  • Shared writer and reader rules prevent ad hoc status files from drifting on filenames, fields, stale semantics, and shutdown behavior.
  • ${XDG_STATE_HOME:-~/.local/state} is a good fit for persistent user state that is local to a machine.

Relation to A2A

This project is an A2A-compatible local status layer. It complements A2A rather than replacing it. It does not replace Agent Card discovery, Task APIs, or full A2A service behavior.

A2A answers, "How do agents talk to each other?" This repository answers, "What is running on this machine right now?"

See:

  • docs/agent-status-v1alpha1.md
  • docs/a2a-compat.md

Install

Python 3.10+.

From PyPI:

pip install agent-status

Manual setup:

python3 -m venv .venv
. .venv/bin/activate
pip install -e .

Devbox alternative:

devbox shell
python -m pip install -e .

Devbox uses same .venv path via VENV_DIR=.venv.

Pi extension install

Pi package lives in pi-extension/, exported from repo root package.json like ponytail.

Install from local checkout:

pi install /path/to/astatus

Do not install ./pi-extension directly. Repo root package.json exports extension. After install in running pi session, run /reload or restart pi so session_start fires for new extension.

Install from git:

pi install git:github.com/you/astatus

One-shot test without install:

pi -e ./pi-extension/index.js

Build

Build a wheel and source distribution:

python -m pip install build
python -m build

Install from built wheel in a fresh environment:

python -m venv /tmp/astatus-smoke
. /tmp/astatus-smoke/bin/activate
pip install dist/*.whl
agent-status --help

Quick start

Emit one snapshot:

RUN_ID="pi-$(python3 - <<'PY'
import uuid
print(uuid.uuid4().hex)
PY
)"

python3 -m agent_status emit \
  --agent-id "$RUN_ID" \
  --agent-name pi \
  --lifecycle running \
  --workspace "$PWD" \
  --pid $$ \
  --task-id task-123 \
  --task-state working \
  --task-summary "refactor scheduler tests" \
  --task-status-timestamp 2026-06-20T16:44:55Z

agent_id must be unique per running agent instance. Do not derive it from PID alone: sandboxed sessions can share same PID and collide. runtime.pid is descriptive metadata only.

List snapshots:

python3 -m agent_status list

Get one snapshot:

python3 -m agent_status get "$RUN_ID"

Watch snapshots:

python3 -m agent_status watch --interval 2

Prune old stale or stopped snapshots:

python3 -m agent_status prune --prune-after 86400

Validate a file:

python3 -m agent_status validate examples/sample-status.json

Protocol summary

Default status directory:

${AGENT_STATUS_DIR:-${XDG_STATE_HOME:-~/.local/state}/agent-status}

One running agent instance maps to one file:

<agent_id>.json

Core required fields:

  • schema_version
  • agent_id
  • agent_name
  • runtime.lifecycle
  • runtime.updated_at

Task state uses A2A-style values. idle, stale, and missing are derived by readers and are never written directly.

JSON example

{
  "schema_version": "agent-status/v1alpha1",
  "agent_id": "pi-7d5d6ca5e54c44cfb9e8d5acfd3c71a1",
  "agent_name": "pi",
  "runtime": {
    "lifecycle": "running",
    "updated_at": "2026-06-20T16:45:00Z",
    "last_activity_at": "2026-06-20T16:44:52Z",
    "pid": 12345,
    "workspace": "/home/julien/src/project"
  },
  "task": {
    "id": "task-123",
    "context_id": "ctx-456",
    "state": "working",
    "summary": "refactor scheduler tests",
    "status_timestamp": "2026-06-20T16:44:55Z"
  }
}

CLI examples

After installation, you can also use the entry point directly:

agent-status emit --agent-id "pi-$(python3 - <<'PY'
import uuid
print(uuid.uuid4().hex)
PY
)" --agent-name pi --lifecycle running
agent-status list
agent-status get <agent-id>
agent-status watch
agent-status prune --prune-after 86400
agent-status validate examples/sample-status.json

Writer rules

  • Write the whole file atomically.
  • agent_id must be unique per running instance. PID-only IDs like pi-12345 are unsafe under PID namespaces or sandboxes.
  • Use an absolute workspace path when it is known.
  • Update on lifecycle changes, task changes, summary changes, and heartbeats.
  • Send a heartbeat every 15 to 30 seconds.
  • On clean exit, either remove the file or persist runtime.lifecycle=stopped.
  • If you use temp files for atomic writes, temp names need random or OS-guaranteed uniqueness. Do not rely on PID suffixes.

Stale semantics

The default stale_after value is 60 seconds.

A reader marks a record as stale when:

now - runtime.updated_at > stale_after

If runtime.lifecycle=running and there is no task, a reader may render the agent as idle.

A stale file is not definitive proof that the writer is gone permanently. The agent may be crashed, suspended, disconnected, or simply slow. Readers should mark records as stale rather than deleting them silently. Cleanup is a separate operator policy.

The reference CLI provides explicit cleanup:

agent-status prune --prune-after 86400

The default prune policy removes snapshots older than 24 hours if they are already stale, along with older snapshots whose runtime.lifecycle is stopped.

Validation

Run tests:

python3 -m unittest

Validate examples:

python3 -m agent_status validate examples/sample-status.json
python3 -m agent_status validate examples/a2a-linked-status.json

Roadmap

Possible future additions:

  • HTTP exporter
  • registry bridge
  • richer TUI or shell integrations

Out of scope for now:

  • registry server
  • full A2A server
  • orchestration layer
  • history store

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

agent_status-0.1.4.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

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

agent_status-0.1.4-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file agent_status-0.1.4.tar.gz.

File metadata

  • Download URL: agent_status-0.1.4.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agent_status-0.1.4.tar.gz
Algorithm Hash digest
SHA256 ae6b60418120ce56fc5769dfe8c907d476ca5d75b9c98e10b72e54bebd730051
MD5 028961bbb57e7a2c947a6b50c8d9d08d
BLAKE2b-256 d88ee1682bc9d2e72d548a56e02281dc6b9e57319382b71e995937d092621242

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_status-0.1.4.tar.gz:

Publisher: publish-pypi.yml on julsemaan/astatus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agent_status-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: agent_status-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agent_status-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8a1d67eed8170473fbc3e0240e6a48992cc0261a02ff525b892215f5a208e727
MD5 2dc03bbf5b0800fddcdb8f712f0c02a0
BLAKE2b-256 170b5f36791d735874db693f414d4821cfcc4b117bcb82a24c77994602318af0

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_status-0.1.4-py3-none-any.whl:

Publisher: publish-pypi.yml on julsemaan/astatus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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