agentcard-disco 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentcard_disco-0.1.0/.github/workflows/ci.yml +71 -0
- agentcard_disco-0.1.0/.github/workflows/publish.yml +49 -0
- agentcard_disco-0.1.0/.gitignore +49 -0
- agentcard_disco-0.1.0/PKG-INFO +212 -0
- agentcard_disco-0.1.0/README.md +186 -0
- agentcard_disco-0.1.0/USAGE.md +141 -0
- agentcard_disco-0.1.0/pyproject.toml +69 -0
- agentcard_disco-0.1.0/src/agentcard_disco/__init__.py +4 -0
- agentcard_disco-0.1.0/src/agentcard_disco/cli/__init__.py +5 -0
- agentcard_disco-0.1.0/src/agentcard_disco/cli/main.py +379 -0
- agentcard_disco-0.1.0/src/agentcard_disco/models/__init__.py +19 -0
- agentcard_disco-0.1.0/src/agentcard_disco/models/agent_card.py +262 -0
- agentcard_disco-0.1.0/src/agentcard_disco/parser/__init__.py +5 -0
- agentcard_disco-0.1.0/src/agentcard_disco/parser/loader.py +180 -0
- agentcard_disco-0.1.0/src/agentcard_disco/reporting/__init__.py +13 -0
- agentcard_disco-0.1.0/src/agentcard_disco/reporting/exporters.py +205 -0
- agentcard_disco-0.1.0/src/agentcard_disco/reporting/terminal.py +263 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/__init__.py +22 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/ai_quality.py +333 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/completeness.py +222 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/engine.py +129 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/metadata_richness.py +257 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/result.py +130 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/search_alignment.py +276 -0
- agentcard_disco-0.1.0/src/agentcard_disco/scoring/semantic_specificity.py +279 -0
- agentcard_disco-0.1.0/tests/__init__.py +0 -0
- agentcard_disco-0.1.0/tests/fixtures/good_card.json +75 -0
- agentcard_disco-0.1.0/tests/fixtures/minimal_card.json +19 -0
- agentcard_disco-0.1.0/tests/unit/__init__.py +0 -0
- agentcard_disco-0.1.0/tests/unit/test_ai_quality.py +202 -0
- agentcard_disco-0.1.0/tests/unit/test_phase1.py +152 -0
- agentcard_disco-0.1.0/tests/unit/test_phase2.py +272 -0
- agentcard_disco-0.1.0/tests/unit/test_phase3.py +241 -0
- agentcard_disco-0.1.0/tests/unit/test_url_loader.py +137 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main", "master"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main", "master"]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
pip install -e ".[deep]"
|
|
30
|
+
pip install pytest pytest-cov
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: pytest tests/ -v --cov=src/agentcard_disco --cov-report=term-missing
|
|
34
|
+
|
|
35
|
+
lint:
|
|
36
|
+
name: Lint
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
|
|
42
|
+
- name: Set up Python
|
|
43
|
+
uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: "3.12"
|
|
46
|
+
|
|
47
|
+
- name: Install ruff
|
|
48
|
+
run: pip install ruff
|
|
49
|
+
|
|
50
|
+
- name: Run ruff
|
|
51
|
+
run: ruff check src/
|
|
52
|
+
|
|
53
|
+
typecheck:
|
|
54
|
+
name: Type check
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
|
|
60
|
+
- name: Set up Python
|
|
61
|
+
uses: actions/setup-python@v5
|
|
62
|
+
with:
|
|
63
|
+
python-version: "3.12"
|
|
64
|
+
|
|
65
|
+
- name: Install dependencies
|
|
66
|
+
run: |
|
|
67
|
+
pip install -e ".[deep]"
|
|
68
|
+
pip install mypy
|
|
69
|
+
|
|
70
|
+
- name: Run mypy
|
|
71
|
+
run: mypy src/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*" # triggers on: git tag v0.1.0 && git push --tags
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distribution
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install build tools
|
|
22
|
+
run: pip install hatch
|
|
23
|
+
|
|
24
|
+
- name: Build wheel and sdist
|
|
25
|
+
run: hatch build
|
|
26
|
+
|
|
27
|
+
- name: Upload dist as artifact
|
|
28
|
+
uses: actions/upload-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: dist
|
|
31
|
+
path: dist/
|
|
32
|
+
|
|
33
|
+
publish:
|
|
34
|
+
name: Publish to PyPI
|
|
35
|
+
needs: build
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
environment: pypi
|
|
38
|
+
permissions:
|
|
39
|
+
id-token: write # required for trusted publishing
|
|
40
|
+
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download dist artifact
|
|
43
|
+
uses: actions/download-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: dist
|
|
46
|
+
path: dist/
|
|
47
|
+
|
|
48
|
+
- name: Publish to PyPI
|
|
49
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Environment / secrets
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
!.env.example
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*.pyo
|
|
10
|
+
*.pyd
|
|
11
|
+
*.egg
|
|
12
|
+
*.egg-info/
|
|
13
|
+
dist/
|
|
14
|
+
build/
|
|
15
|
+
.eggs/
|
|
16
|
+
*.whl
|
|
17
|
+
MANIFEST
|
|
18
|
+
|
|
19
|
+
# Virtual environments
|
|
20
|
+
.venv/
|
|
21
|
+
venv/
|
|
22
|
+
env/
|
|
23
|
+
ENV/
|
|
24
|
+
|
|
25
|
+
# Test / coverage
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
.coverage
|
|
28
|
+
htmlcov/
|
|
29
|
+
coverage.xml
|
|
30
|
+
*.cover
|
|
31
|
+
|
|
32
|
+
# Type checking
|
|
33
|
+
.mypy_cache/
|
|
34
|
+
.dmypy.json
|
|
35
|
+
|
|
36
|
+
# Editors
|
|
37
|
+
.vscode/
|
|
38
|
+
.idea/
|
|
39
|
+
*.swp
|
|
40
|
+
*.swo
|
|
41
|
+
*~
|
|
42
|
+
|
|
43
|
+
# OS
|
|
44
|
+
.DS_Store
|
|
45
|
+
Thumbs.db
|
|
46
|
+
|
|
47
|
+
# Reports (generated output)
|
|
48
|
+
report.json
|
|
49
|
+
report.md
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentcard-disco
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Score and optimize A2A Agent Cards for discoverability
|
|
5
|
+
Project-URL: Homepage, https://github.com/chinemeze/agentcard-disco
|
|
6
|
+
Project-URL: Issues, https://github.com/chinemeze/agentcard-disco/issues
|
|
7
|
+
Author: Chinemeze
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: a2a,agent,agent-card,discoverability,llm
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: click>=8.1
|
|
19
|
+
Requires-Dist: httpx>=0.27
|
|
20
|
+
Requires-Dist: pydantic>=2.0
|
|
21
|
+
Requires-Dist: python-dotenv>=1.0
|
|
22
|
+
Requires-Dist: rich>=13.0
|
|
23
|
+
Provides-Extra: deep
|
|
24
|
+
Requires-Dist: google-genai>=1.0; extra == 'deep'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# agentcard-disco
|
|
28
|
+
|
|
29
|
+
**Score and optimise [A2A](https://agent2agent.info/) Agent Cards for discoverability.**
|
|
30
|
+
|
|
31
|
+
`agentcard-disco` analyses an Agent Card JSON file and gives it a discoverability score across four heuristic dimensions (plus optional AI-assisted analysis), surfacing exactly what to fix before publishing to an A2A registry.
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
35
|
+
│ agentcard-disco discoverability score │
|
|
36
|
+
│ │
|
|
37
|
+
│ 🏆 DataPulse Analytics Agent │
|
|
38
|
+
│ Source: tests/fixtures/good_card.json │
|
|
39
|
+
│ │
|
|
40
|
+
│ Score: 88.0 / 100 (88%) Grade: A │
|
|
41
|
+
└─────────────────────────────────────────────────────────────┘
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install agentcard-disco
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For AI-assisted scoring (`--deep`):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install "agentcard-disco[deep]"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Score a local card
|
|
64
|
+
agentcard-disco score ./agent-card.json
|
|
65
|
+
|
|
66
|
+
# Score from a URL
|
|
67
|
+
agentcard-disco score https://api.example.com/.well-known/agent-card.json
|
|
68
|
+
|
|
69
|
+
# + AI quality analysis (requires GEMINI_API_KEY in .env)
|
|
70
|
+
agentcard-disco score ./agent-card.json --deep
|
|
71
|
+
|
|
72
|
+
# Export report as JSON or Markdown
|
|
73
|
+
agentcard-disco score ./agent-card.json --format json --output report.json
|
|
74
|
+
agentcard-disco score ./agent-card.json --format markdown --output report.md
|
|
75
|
+
|
|
76
|
+
# CI gate — exit 1 if score is below 70%
|
|
77
|
+
agentcard-disco score ./agent-card.json --fail-under 70
|
|
78
|
+
|
|
79
|
+
# Get improvement suggestions only
|
|
80
|
+
agentcard-disco suggest ./agent-card.json --priority high
|
|
81
|
+
|
|
82
|
+
# Compare two cards side-by-side
|
|
83
|
+
agentcard-disco compare ./v1.json ./v2.json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Scoring dimensions
|
|
89
|
+
|
|
90
|
+
| Dimension | Points | What it measures |
|
|
91
|
+
|-----------|-------:|-----------------|
|
|
92
|
+
| Metadata Richness | 0–30 | Description length, tags, examples, provider info |
|
|
93
|
+
| Semantic Specificity | 0–30 | Filler-word ratio, skill distinctness, action-verb density |
|
|
94
|
+
| Search Alignment | 0–20 | Tag and keyword coverage vs A2A registry query vocabulary |
|
|
95
|
+
| Completeness | 0–20 | SemVer, capabilities, auth declaration, protocol version |
|
|
96
|
+
| AI Quality *(--deep)* | 0–20 | Categorical quality judgments via Gemini |
|
|
97
|
+
|
|
98
|
+
**Grade scale:**
|
|
99
|
+
|
|
100
|
+
| Grade | Score |
|
|
101
|
+
|-------|-------|
|
|
102
|
+
| A | 85–100% |
|
|
103
|
+
| B | 70–84% |
|
|
104
|
+
| C | 50–69% |
|
|
105
|
+
| D | 30–49% |
|
|
106
|
+
| F | 0–29% |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## AI scoring setup (`--deep`)
|
|
111
|
+
|
|
112
|
+
1. Install the deep extra: `pip install "agentcard-disco[deep]"`
|
|
113
|
+
2. Get a free Gemini API key at https://aistudio.google.com/app/apikey
|
|
114
|
+
3. Add it to a `.env` file in your working directory:
|
|
115
|
+
|
|
116
|
+
```env
|
|
117
|
+
GEMINI_API_KEY="AIza..."
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
4. Run with `--deep`:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
agentcard-disco score ./agent-card.json --deep
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Python API
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from agentcard_disco.parser import load
|
|
132
|
+
from agentcard_disco.scoring.engine import score
|
|
133
|
+
|
|
134
|
+
card = load("agent-card.json") # also accepts http(s):// URLs
|
|
135
|
+
report = score(card) # Tier 1 only
|
|
136
|
+
report = score(card, deep=True) # + AI analysis
|
|
137
|
+
|
|
138
|
+
print(report.grade.value) # "A", "B", ...
|
|
139
|
+
print(report.percentage) # 88.0
|
|
140
|
+
print(report.total_score) # 88.0
|
|
141
|
+
|
|
142
|
+
for suggestion in report.all_suggestions:
|
|
143
|
+
print(suggestion.priority, suggestion.field, suggestion.message)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Commands
|
|
149
|
+
|
|
150
|
+
### `score`
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
agentcard-disco score SOURCE [OPTIONS]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
| Option | Default | Description |
|
|
157
|
+
|--------|---------|-------------|
|
|
158
|
+
| `--deep` | off | Enable Tier 2 AI analysis (+20 pts) |
|
|
159
|
+
| `--format` | terminal | `terminal`, `json`, or `markdown` |
|
|
160
|
+
| `--output FILE` | stdout | Write output to file |
|
|
161
|
+
| `--fail-under SCORE` | — | Exit 1 if percentage < SCORE |
|
|
162
|
+
| `--no-suggestions` | off | Hide suggestions table |
|
|
163
|
+
| `--no-detail` | off | Hide per-dimension details |
|
|
164
|
+
|
|
165
|
+
### `suggest`
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
agentcard-disco suggest SOURCE [OPTIONS]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
| Option | Default | Description |
|
|
172
|
+
|--------|---------|-------------|
|
|
173
|
+
| `--priority` | all | Filter: `all`, `high`, `medium`, `low` |
|
|
174
|
+
| `--format` | terminal | `terminal` or `json` |
|
|
175
|
+
| `--limit N` | 20 | Max suggestions to show |
|
|
176
|
+
| `--deep` | off | Include AI suggestions |
|
|
177
|
+
|
|
178
|
+
### `compare`
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
agentcard-disco compare SOURCE SOURCE [SOURCE ...] [OPTIONS]
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
| Option | Default | Description |
|
|
185
|
+
|--------|---------|-------------|
|
|
186
|
+
| `--format` | terminal | `terminal` or `json` |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Development
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
git clone https://github.com/chinemeze/agentcard-disco
|
|
194
|
+
cd agentcard-disco
|
|
195
|
+
pip install -e ".[deep]"
|
|
196
|
+
pip install pytest pytest-cov mypy ruff
|
|
197
|
+
|
|
198
|
+
# Run tests
|
|
199
|
+
pytest tests/ -v
|
|
200
|
+
|
|
201
|
+
# Lint
|
|
202
|
+
ruff check src/
|
|
203
|
+
|
|
204
|
+
# Type check
|
|
205
|
+
mypy src/
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## License
|
|
211
|
+
|
|
212
|
+
MIT
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# agentcard-disco
|
|
2
|
+
|
|
3
|
+
**Score and optimise [A2A](https://agent2agent.info/) Agent Cards for discoverability.**
|
|
4
|
+
|
|
5
|
+
`agentcard-disco` analyses an Agent Card JSON file and gives it a discoverability score across four heuristic dimensions (plus optional AI-assisted analysis), surfacing exactly what to fix before publishing to an A2A registry.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ agentcard-disco discoverability score │
|
|
10
|
+
│ │
|
|
11
|
+
│ 🏆 DataPulse Analytics Agent │
|
|
12
|
+
│ Source: tests/fixtures/good_card.json │
|
|
13
|
+
│ │
|
|
14
|
+
│ Score: 88.0 / 100 (88%) Grade: A │
|
|
15
|
+
└─────────────────────────────────────────────────────────────┘
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install agentcard-disco
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
For AI-assisted scoring (`--deep`):
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install "agentcard-disco[deep]"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Score a local card
|
|
38
|
+
agentcard-disco score ./agent-card.json
|
|
39
|
+
|
|
40
|
+
# Score from a URL
|
|
41
|
+
agentcard-disco score https://api.example.com/.well-known/agent-card.json
|
|
42
|
+
|
|
43
|
+
# + AI quality analysis (requires GEMINI_API_KEY in .env)
|
|
44
|
+
agentcard-disco score ./agent-card.json --deep
|
|
45
|
+
|
|
46
|
+
# Export report as JSON or Markdown
|
|
47
|
+
agentcard-disco score ./agent-card.json --format json --output report.json
|
|
48
|
+
agentcard-disco score ./agent-card.json --format markdown --output report.md
|
|
49
|
+
|
|
50
|
+
# CI gate — exit 1 if score is below 70%
|
|
51
|
+
agentcard-disco score ./agent-card.json --fail-under 70
|
|
52
|
+
|
|
53
|
+
# Get improvement suggestions only
|
|
54
|
+
agentcard-disco suggest ./agent-card.json --priority high
|
|
55
|
+
|
|
56
|
+
# Compare two cards side-by-side
|
|
57
|
+
agentcard-disco compare ./v1.json ./v2.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Scoring dimensions
|
|
63
|
+
|
|
64
|
+
| Dimension | Points | What it measures |
|
|
65
|
+
|-----------|-------:|-----------------|
|
|
66
|
+
| Metadata Richness | 0–30 | Description length, tags, examples, provider info |
|
|
67
|
+
| Semantic Specificity | 0–30 | Filler-word ratio, skill distinctness, action-verb density |
|
|
68
|
+
| Search Alignment | 0–20 | Tag and keyword coverage vs A2A registry query vocabulary |
|
|
69
|
+
| Completeness | 0–20 | SemVer, capabilities, auth declaration, protocol version |
|
|
70
|
+
| AI Quality *(--deep)* | 0–20 | Categorical quality judgments via Gemini |
|
|
71
|
+
|
|
72
|
+
**Grade scale:**
|
|
73
|
+
|
|
74
|
+
| Grade | Score |
|
|
75
|
+
|-------|-------|
|
|
76
|
+
| A | 85–100% |
|
|
77
|
+
| B | 70–84% |
|
|
78
|
+
| C | 50–69% |
|
|
79
|
+
| D | 30–49% |
|
|
80
|
+
| F | 0–29% |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## AI scoring setup (`--deep`)
|
|
85
|
+
|
|
86
|
+
1. Install the deep extra: `pip install "agentcard-disco[deep]"`
|
|
87
|
+
2. Get a free Gemini API key at https://aistudio.google.com/app/apikey
|
|
88
|
+
3. Add it to a `.env` file in your working directory:
|
|
89
|
+
|
|
90
|
+
```env
|
|
91
|
+
GEMINI_API_KEY="AIza..."
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
4. Run with `--deep`:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
agentcard-disco score ./agent-card.json --deep
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Python API
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from agentcard_disco.parser import load
|
|
106
|
+
from agentcard_disco.scoring.engine import score
|
|
107
|
+
|
|
108
|
+
card = load("agent-card.json") # also accepts http(s):// URLs
|
|
109
|
+
report = score(card) # Tier 1 only
|
|
110
|
+
report = score(card, deep=True) # + AI analysis
|
|
111
|
+
|
|
112
|
+
print(report.grade.value) # "A", "B", ...
|
|
113
|
+
print(report.percentage) # 88.0
|
|
114
|
+
print(report.total_score) # 88.0
|
|
115
|
+
|
|
116
|
+
for suggestion in report.all_suggestions:
|
|
117
|
+
print(suggestion.priority, suggestion.field, suggestion.message)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Commands
|
|
123
|
+
|
|
124
|
+
### `score`
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
agentcard-disco score SOURCE [OPTIONS]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
| Option | Default | Description |
|
|
131
|
+
|--------|---------|-------------|
|
|
132
|
+
| `--deep` | off | Enable Tier 2 AI analysis (+20 pts) |
|
|
133
|
+
| `--format` | terminal | `terminal`, `json`, or `markdown` |
|
|
134
|
+
| `--output FILE` | stdout | Write output to file |
|
|
135
|
+
| `--fail-under SCORE` | — | Exit 1 if percentage < SCORE |
|
|
136
|
+
| `--no-suggestions` | off | Hide suggestions table |
|
|
137
|
+
| `--no-detail` | off | Hide per-dimension details |
|
|
138
|
+
|
|
139
|
+
### `suggest`
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
agentcard-disco suggest SOURCE [OPTIONS]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Option | Default | Description |
|
|
146
|
+
|--------|---------|-------------|
|
|
147
|
+
| `--priority` | all | Filter: `all`, `high`, `medium`, `low` |
|
|
148
|
+
| `--format` | terminal | `terminal` or `json` |
|
|
149
|
+
| `--limit N` | 20 | Max suggestions to show |
|
|
150
|
+
| `--deep` | off | Include AI suggestions |
|
|
151
|
+
|
|
152
|
+
### `compare`
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
agentcard-disco compare SOURCE SOURCE [SOURCE ...] [OPTIONS]
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
| Option | Default | Description |
|
|
159
|
+
|--------|---------|-------------|
|
|
160
|
+
| `--format` | terminal | `terminal` or `json` |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Development
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
git clone https://github.com/chinemeze/agentcard-disco
|
|
168
|
+
cd agentcard-disco
|
|
169
|
+
pip install -e ".[deep]"
|
|
170
|
+
pip install pytest pytest-cov mypy ruff
|
|
171
|
+
|
|
172
|
+
# Run tests
|
|
173
|
+
pytest tests/ -v
|
|
174
|
+
|
|
175
|
+
# Lint
|
|
176
|
+
ruff check src/
|
|
177
|
+
|
|
178
|
+
# Type check
|
|
179
|
+
mypy src/
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# agentcard-disco — Usage Guide
|
|
2
|
+
|
|
3
|
+
Score and optimise A2A Agent Cards for discoverability.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd agentcard-disco
|
|
11
|
+
|
|
12
|
+
# Tier 1 only (no AI, no API key needed)
|
|
13
|
+
pip install -e .
|
|
14
|
+
|
|
15
|
+
# Tier 1 + Tier 2 AI scoring
|
|
16
|
+
pip install -e ".[deep]"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
Copy the example below into `.env` at the project root.
|
|
24
|
+
Only needed if you want `--deep` AI scoring.
|
|
25
|
+
|
|
26
|
+
```env
|
|
27
|
+
GEMINI_API_KEY="your-key-here"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Get a free key at: https://aistudio.google.com/app/apikey
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
### `score` — full discoverability report
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
agentcard-disco score <source>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| Option | Description |
|
|
43
|
+
|--------|-------------|
|
|
44
|
+
| `--deep` | Enable Tier 2 AI analysis (+20 pts). Requires `GEMINI_API_KEY`. |
|
|
45
|
+
| `--format terminal\|json\|markdown` | Output format (default: terminal) |
|
|
46
|
+
| `--output FILE` | Write output to a file |
|
|
47
|
+
| `--fail-under SCORE` | Exit code 1 if score % is below this (useful in CI) |
|
|
48
|
+
| `--no-suggestions` | Hide the suggestions table |
|
|
49
|
+
| `--no-detail` | Hide per-dimension check/fail details |
|
|
50
|
+
|
|
51
|
+
**Examples:**
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
agentcard-disco score ./agent-card.json
|
|
55
|
+
agentcard-disco score ./agent-card.json --deep
|
|
56
|
+
agentcard-disco score ./agent-card.json --format json --output report.json
|
|
57
|
+
agentcard-disco score ./agent-card.json --format markdown --output report.md
|
|
58
|
+
agentcard-disco score ./agent-card.json --fail-under 70
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### `suggest` — improvement suggestions only
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
agentcard-disco suggest <source>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Option | Description |
|
|
70
|
+
|--------|-------------|
|
|
71
|
+
| `--priority all\|high\|medium\|low` | Filter by priority (default: all) |
|
|
72
|
+
| `--format terminal\|json` | Output format (default: terminal) |
|
|
73
|
+
| `--limit N` | Max number of suggestions to show (default: 20) |
|
|
74
|
+
| `--deep` | Include AI-powered suggestions |
|
|
75
|
+
|
|
76
|
+
**Examples:**
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
agentcard-disco suggest ./agent-card.json
|
|
80
|
+
agentcard-disco suggest ./agent-card.json --priority high
|
|
81
|
+
agentcard-disco suggest ./agent-card.json --format json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### `compare` — side-by-side comparison
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
agentcard-disco compare <source1> <source2> [source3 ...]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
| Option | Description |
|
|
93
|
+
|--------|-------------|
|
|
94
|
+
| `--format terminal\|json` | Output format (default: terminal) |
|
|
95
|
+
|
|
96
|
+
**Examples:**
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
agentcard-disco compare ./card-a.json ./card-b.json
|
|
100
|
+
agentcard-disco compare ./v1.json ./v2.json ./v3.json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Scoring
|
|
106
|
+
|
|
107
|
+
| Dimension | Points | Tier |
|
|
108
|
+
|-----------|-------:|------|
|
|
109
|
+
| Metadata Richness | 0–30 | 1 |
|
|
110
|
+
| Semantic Specificity | 0–30 | 1 |
|
|
111
|
+
| Search Alignment | 0–20 | 1 |
|
|
112
|
+
| Completeness | 0–20 | 1 |
|
|
113
|
+
| AI Quality (`--deep`) | 0–20 | 2 |
|
|
114
|
+
|
|
115
|
+
**Grade scale** (based on %):
|
|
116
|
+
|
|
117
|
+
| Grade | Range |
|
|
118
|
+
|-------|-------|
|
|
119
|
+
| A | 85–100% |
|
|
120
|
+
| B | 70–84% |
|
|
121
|
+
| C | 50–69% |
|
|
122
|
+
| D | 30–49% |
|
|
123
|
+
| F | 0–29% |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Running Tests
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pip install pytest pytest-asyncio
|
|
131
|
+
pytest tests/ -v
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Source can be a local file or a URL
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
agentcard-disco score ./local-card.json
|
|
140
|
+
agentcard-disco score https://api.example.com/.well-known/agent-card.json
|
|
141
|
+
```
|