Skip to content

Commit dc760f4

Browse files
committed
Initial release of agent-readable
A lightweight Python protocol giving library authors a place to put behavioral rules — pre-conditions, lifecycle, anti-patterns — where AI coding agents will reliably find them. Defines __agent_help__ (full custom output) and __agent_notes__ (additive, MRO-accumulated guidance), with AgentReadableMixin, agent_help() dispatch, module support, and a CLI.
0 parents  commit dc760f4

18 files changed

Lines changed: 2281 additions & 0 deletions

.github/workflows/publish.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v3
16+
17+
- name: Build sdist + wheel
18+
run: uv build
19+
20+
- name: Upload artifacts
21+
uses: actions/upload-artifact@v4
22+
with:
23+
name: dist
24+
path: dist/
25+
26+
publish-pypi:
27+
needs: build
28+
runs-on: ubuntu-latest
29+
environment: pypi
30+
permissions:
31+
# Required for PyPI Trusted Publishing (OIDC).
32+
# Configure the trusted publisher on PyPI before the first tag push.
33+
id-token: write
34+
steps:
35+
- name: Download artifacts
36+
uses: actions/download-artifact@v4
37+
with:
38+
name: dist
39+
path: dist/
40+
41+
- name: Publish to PyPI
42+
uses: pypa/gh-action-pypi-publish@release/v1
43+
44+
github-release:
45+
needs: publish-pypi
46+
runs-on: ubuntu-latest
47+
permissions:
48+
contents: write
49+
steps:
50+
- name: Download artifacts
51+
uses: actions/download-artifact@v4
52+
with:
53+
name: dist
54+
path: dist/
55+
56+
- name: Create GitHub Release
57+
uses: softprops/action-gh-release@v2
58+
with:
59+
files: dist/*
60+
generate_release_notes: true

.github/workflows/test.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v3
22+
23+
- name: Set up Python ${{ matrix.python-version }}
24+
run: uv python install ${{ matrix.python-version }}
25+
26+
- name: Install project + dev deps
27+
run: uv sync --python ${{ matrix.python-version }} --group dev
28+
29+
- name: Run tests
30+
run: uv run --python ${{ matrix.python-version }} pytest
31+
32+
- name: Smoke-test examples
33+
run: |
34+
for f in examples/*.py; do
35+
echo "--- $f ---"
36+
uv run --python ${{ matrix.python-version }} python "$f" > /dev/null
37+
done

.gitignore

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
7+
# Distribution / packaging
8+
build/
9+
dist/
10+
*.egg-info/
11+
*.egg
12+
.eggs/
13+
14+
# Virtual environments
15+
.venv/
16+
venv/
17+
env/
18+
19+
# Testing
20+
.pytest_cache/
21+
.coverage
22+
htmlcov/
23+
.tox/
24+
.nox/
25+
26+
# Type checking
27+
.mypy_cache/
28+
.pytype/
29+
30+
# IDE
31+
.vscode/
32+
.idea/
33+
*.swp
34+
*.swo
35+
*~
36+
37+
# OS
38+
.DS_Store
39+
Thumbs.db
40+
41+
# Hatch
42+
hatch.toml
43+
44+
# No external dependencies for this project, and uv.lock is only needed for local dev.
45+
uv.lock

AGENT-PROMPT.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Coding Agent Instructions — agent-readable
2+
3+
This repository uses `agent-readable`. Install if needed: `pip install agent-readable`
4+
5+
## Before using or modifying a class or module
6+
7+
Do not guess. Run this first:
8+
9+
```python
10+
from agent_readable import agent_help
11+
12+
print(agent_help(ClassName))
13+
# or: python -m agent_readable package.module:ClassName
14+
15+
# or
16+
print(agent_help(package.module))
17+
# or: python -m agent_readable package.module
18+
```
19+
20+
Treat the output as the canonical usage guide. Follow do/don't rules, anti-patterns, and lifecycle constraints exactly. Do not invent behavior that contradicts it.
21+
22+
After modifying a class, prefer docstrings first — only update `__agent_notes__()` for corner cases docstrings cannot express. Verify `agent_help(ClassName)` is still accurate.
23+
24+
## Making a class agent-readable
25+
26+
**New class** — inherit `AgentReadableMixin`:
27+
28+
```python
29+
from agent_readable import AgentReadableMixin
30+
31+
32+
class ResourcePool(AgentReadableMixin):
33+
"""
34+
Rotates interchangeable resources such as API keys.
35+
36+
Agent usage:
37+
Run ``agent_help(ResourcePool)`` before using this class in generated code.
38+
"""
39+
40+
def __init__(self, resources, *, cooldown: float = 60): ...
41+
42+
def call(self, fn):
43+
"""Call fn(resource) with automatic rotation and retry."""
44+
45+
@classmethod
46+
def __agent_notes__(cls) -> str:
47+
return """
48+
## Do
49+
50+
- Use `call()` for normal non-streaming requests.
51+
52+
## Do not
53+
54+
- Do not use for streaming requests.
55+
"""
56+
```
57+
58+
**Wrapping an existing class** — just mix in:
59+
60+
```python
61+
class Connection(sqlite3.Connection, AgentReadableMixin):
62+
"""An agent-friendly wrapper around sqlite3.Connection."""
63+
```
64+
65+
Guidelines:
66+
67+
- Class docstring → "Purpose" section. Method docstrings → "Public API" summaries.
68+
- Override `__agent_notes__()` only for corner cases and anti-patterns. The mixin is not required for notes — Defining `__agent_notes__()` on any class (or monkey-patching it onto a third-party class) is enough; `agent_help()` collects it from the MRO automatically.
69+
- Add an "Agent usage" hint in the docstring — agents see it even via `help()`.
70+
- Simple data-only classes do not need agent docs.
71+
72+
## Making a module agent-readable
73+
74+
Modules are auto-documented — `agent_help()` generates docs from the module docstring and public members.
75+
76+
**Do not override `__agent_help__` on a module unless absolutely necessary.** Unlike classes (which have `__agent_notes__()` to append guidance), overriding `__agent_help__` on a module replaces the auto-generated summary entirely — you lose signatures, purpose, and public API listing. Prefer writing clear docstrings on the module and its functions/classes instead.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 zydo and agent-readable contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)