diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 9a10bab..c0aa388 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -37,7 +37,7 @@ cargo doc --workspace --no-deps ## Benchmark Automation -The benchmarks workflow runs all 13 benchmark modules (237 benchmarks total), generates a Markdown results page, and commits it to `book/src/reference/benchmarks.md`. This triggers the docs workflow to redeploy GitHub Pages with fresh numbers. +The benchmarks workflow runs all 13 benchmark modules (267 benchmarks total), generates a Markdown results page and an interactive dashboard, and commits them to `book/src/reference/benchmarks.md` and `book/src/reference/benchmark-dashboard.html`. This triggers the docs workflow to redeploy GitHub Pages with fresh numbers. ## License diff --git a/CHANGELOG.md b/CHANGELOG.md index 512d723..6f1fe69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 deserialization (~15-25% fewer allocations). - **SSE frame building uses thread-local reusable buffer** — Amortized 0 allocations per event vs previous 1 allocation per event. -- **237 benchmarks, zero panics, zero errors** — Cleanest benchmark run in +- **267 benchmarks, zero panics, zero errors** — Cleanest benchmark run in project history. All 13 benchmark suites (transport, protocol, lifecycle, concurrency, cross-language, realistic, error paths, backpressure, data volume, memory, enterprise, production, advanced) pass with zero failures. @@ -94,7 +94,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 for 5 additional benchmark groups based on CI analysis: `transport/payload_scaling` (8s→10s), `concurrent/sends` (18s→30s), `realistic/payload_complexity` (10s→15s), `realistic/connection` (10s→15s), `enterprise/client_interceptors` (8s→10s). - All 237 benchmarks now complete within their budget on CI runners. + All 267 benchmarks now complete within their budget on CI runners. - **Push config benchmark per-task limit** — `production/push_config/set_roundtrip` and `delete_roundtrip` now upsert a pre-created config instead of creating new configs each iteration, preventing `push config limit exceeded` panics during diff --git a/CITATION.cff b/CITATION.cff index 0438d9a..1eb0475 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -12,7 +12,7 @@ authors: repository-code: "https://github.com/tomtom215/a2a-rust" url: "https://github.com/tomtom215/a2a-rust" license: Apache-2.0 -version: "0.3.0" +version: "0.5.0" date-released: "2026-03-19" keywords: - a2a diff --git a/README.md b/README.md index af81545..f1be619 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ This project aims to be the first **v1.0.0-compliant** Rust SDK for A2A. We inte ```toml [dependencies] -a2a-protocol-sdk = "0.4" +a2a-protocol-sdk = "0.5" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } ``` @@ -297,7 +297,7 @@ cargo fmt --all -- --check # Build documentation RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps -# Run benchmarks (265+ benchmarks across 13 suites — transport, protocol, +# Run benchmarks (267 benchmarks across 13 suites — transport, protocol, # lifecycle, concurrency, cross-language, realistic, error paths, backpressure, # data volume, memory, enterprise, production, and advanced scenarios) cargo bench -p a2a-benchmarks diff --git a/benches/README.md b/benches/README.md index c3bfdb9..28f21db 100644 --- a/benches/README.md +++ b/benches/README.md @@ -63,14 +63,19 @@ benches/ │ ├── backpressure.rs # streaming under load │ ├── data_volume.rs # store ops at scale │ ├── memory_overhead.rs # heap allocation profiling +│ ├── enterprise_scenarios.rs # multi-tenant, CORS, eviction, rate limiting │ ├── production_scenarios.rs # real-world E2E workflows │ └── advanced_scenarios.rs # SDK capability gap coverage +├── dashboard/ +│ └── template.html # Interactive dashboard HTML template ├── cross_language/ │ ├── canonical_agent_card.json # Reference AgentCard for all SDKs │ └── canonical_send_params.json # Reference payload (256 bytes) ├── scripts/ │ ├── run_benchmarks.sh # Run all + collect results │ ├── generate_book_page.sh # Auto-generate book/src/reference/benchmarks.md +│ ├── generate_dashboard.sh # Generate interactive dashboard from criterion data +│ ├── extract_benchmark_json.py # Extract criterion results into structured JSON │ ├── compare_results.sh # Cross-language comparison table │ ├── cross_language_python.sh # Python SDK runner │ ├── cross_language_go.sh # Go SDK runner diff --git a/benches/dashboard/template.html b/benches/dashboard/template.html index 0a94162..55fba11 100644 --- a/benches/dashboard/template.html +++ b/benches/dashboard/template.html @@ -16,39 +16,59 @@ body{font-family:'Space Grotesk',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;min-height:100vh} .mono{font-family:'JetBrains Mono',monospace} a{color:var(--cyan)} -/* Layout */ .wrap{max-width:1280px;margin:0 auto;padding:0 1rem} -header{padding:1.5rem 0;border-bottom:1px solid var(--border)} -header h1{font-size:1.5rem;font-weight:700;display:flex;align-items:center;gap:.75rem;flex-wrap:wrap} -.badge{font-size:.75rem;padding:2px 8px;border-radius:99px;background:var(--surface);border:1px solid var(--border);color:var(--text-sec)} -.subtitle{color:var(--text-sec);font-size:.85rem;margin-top:.25rem} -/* Tabs */ -.tabs{display:flex;gap:2px;overflow-x:auto;border-bottom:1px solid var(--border);margin:1rem 0;-webkit-overflow-scrolling:touch} -.tabs button{background:none;border:none;color:var(--text-sec);padding:.6rem 1rem;font:inherit;font-size:.85rem;cursor:pointer; +header{padding:1.25rem 0;border-bottom:1px solid var(--border)} +header h1{font-size:1.35rem;font-weight:700;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap} +.badge{font-size:.7rem;padding:2px 8px;border-radius:99px;background:var(--surface);border:1px solid var(--border);color:var(--text-sec)} +.subtitle{color:var(--text-sec);font-size:.8rem;margin-top:.2rem} +.tabs{display:flex;gap:2px;overflow-x:auto;border-bottom:1px solid var(--border);margin:.75rem 0;-webkit-overflow-scrolling:touch;scrollbar-width:none} +.tabs::-webkit-scrollbar{display:none} +.tabs button{background:none;border:none;color:var(--text-sec);padding:.5rem .75rem;font:inherit;font-size:.78rem;cursor:pointer; white-space:nowrap;border-bottom:2px solid transparent;transition:color .15s,border-color .15s} .tabs button:hover,.tabs button:focus-visible{color:var(--text)} .tabs button[aria-selected="true"]{color:var(--cyan);border-bottom-color:var(--cyan)} .tabs button:focus-visible{outline:2px solid var(--cyan);outline-offset:-2px;border-radius:4px 4px 0 0} -.tab-panel{display:none;padding:1rem 0} +.tab-panel{display:none;padding:.75rem 0} .tab-panel.active{display:block} -/* Grid */ -.grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))} -.grid-wide{grid-template-columns:repeat(auto-fill,minmax(360px,1fr))} -/* Cards & Metrics */ -.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:1rem;overflow:hidden} -.card h3{font-size:.8rem;color:var(--text-sec);text-transform:uppercase;letter-spacing:.04em;margin-bottom:.75rem} -.metric{text-align:center;padding:.75rem .5rem} -.metric .value{font-family:'JetBrains Mono',monospace;font-size:1.6rem;font-weight:600} -.metric .label{font-size:.75rem;color:var(--text-sec);margin-top:.25rem} -.metric-sm .value{font-size:1.1rem} -.chart-wrap{position:relative;width:100%;aspect-ratio:16/10} -/* Footer */ -footer{border-top:1px solid var(--border);padding:1.5rem 0;margin-top:2rem;color:var(--text-muted);font-size:.75rem;text-align:center} -/* Responsive */ +.grid{display:grid;gap:.75rem;grid-template-columns:repeat(auto-fill,minmax(180px,1fr))} +.grid-wide{display:grid;gap:.75rem;grid-template-columns:repeat(2,1fr)} +.grid-full{display:grid;gap:.75rem;grid-template-columns:1fr} +.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:.75rem;overflow:hidden} +.card h3{font-size:.72rem;color:var(--text-sec);text-transform:uppercase;letter-spacing:.04em;margin-bottom:.5rem} +.card-full{grid-column:1/-1} +.metric{text-align:center;padding:.5rem .25rem} +.metric .value{font-family:'JetBrains Mono',monospace;font-size:1.25rem;font-weight:600} +.metric .label{font-size:.68rem;color:var(--text-sec);margin-top:.15rem} +.chart-wrap{position:relative;width:100%;height:220px} +.chart-wrap-sm{height:180px} +.chart-wrap-lg{height:280px} +.section-title{font-size:.85rem;font-weight:600;color:var(--text);margin:1rem 0 .5rem;padding-bottom:.25rem;border-bottom:1px solid var(--border)} +table.bench-table{width:100%;border-collapse:collapse;font-size:.82rem} +table.bench-table th{text-align:left;color:var(--text-sec);font-weight:600;padding:.5rem .75rem;border-bottom:2px solid var(--border);font-size:.78rem;position:sticky;top:0;background:var(--surface);z-index:1} +table.bench-table td{padding:.4rem .75rem;border-bottom:1px solid var(--border);font-family:'JetBrains Mono',monospace;font-size:.78rem} +table.bench-table tr:hover{background:rgba(0,229,204,.06)} +table.bench-table .group-header td{background:var(--bg);color:var(--cyan);font-family:'Space Grotesk',system-ui,sans-serif;font-weight:600;font-size:.78rem;padding:.6rem .75rem;border-bottom:1px solid var(--border);letter-spacing:.02em} +.table-scroll{max-height:600px;overflow-y:auto;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface)} +.search-box{width:100%;padding:.5rem .75rem;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius); + color:var(--text);font:inherit;font-size:.85rem;margin-bottom:.75rem} +.search-box::placeholder{color:var(--text-muted)} +.result-count{font-size:.75rem;color:var(--text-muted);margin-bottom:.5rem} +footer{border-top:1px solid var(--border);padding:1rem 0;margin-top:1.5rem;color:var(--text-muted);font-size:.7rem;text-align:center} @media(max-width:640px){ - .grid,.grid-wide{grid-template-columns:1fr} - header h1{font-size:1.2rem} - .metric .value{font-size:1.3rem} + .grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))} + .grid-wide{grid-template-columns:1fr} + header h1{font-size:1.1rem} + .metric .value{font-size:1rem} + .chart-wrap{height:180px} + .chart-wrap-sm{height:160px} + .chart-wrap-lg{height:220px} + .tabs button{padding:.4rem .5rem;font-size:.72rem} + .table-scroll{max-height:500px} + table.bench-table{font-size:.72rem} + table.bench-table td,table.bench-table th{padding:.35rem .5rem} +} +@media(min-width:641px) and (max-width:1024px){ + .grid-wide{grid-template-columns:repeat(2,1fr)} } @@ -60,80 +80,94 @@