ai-oriented-a2a 0.3.2__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.
- ai_oriented_a2a-0.3.2/.gitignore +11 -0
- ai_oriented_a2a-0.3.2/CHANGELOG.md +82 -0
- ai_oriented_a2a-0.3.2/LICENSE +21 -0
- ai_oriented_a2a-0.3.2/PKG-INFO +208 -0
- ai_oriented_a2a-0.3.2/README.md +178 -0
- ai_oriented_a2a-0.3.2/SPEC.md +187 -0
- ai_oriented_a2a-0.3.2/ai_oriented_a2a/__init__.py +51 -0
- ai_oriented_a2a-0.3.2/ai_oriented_a2a/protocol.py +232 -0
- ai_oriented_a2a-0.3.2/ai_oriented_a2a/py.typed +0 -0
- ai_oriented_a2a-0.3.2/ai_oriented_a2a/transport.py +273 -0
- ai_oriented_a2a-0.3.2/ai_oriented_a2a/validate.py +93 -0
- ai_oriented_a2a-0.3.2/pyproject.toml +64 -0
- ai_oriented_a2a-0.3.2/schema/absorption-result.schema.json +59 -0
- ai_oriented_a2a-0.3.2/schema/agent-profile.schema.json +44 -0
- ai_oriented_a2a-0.3.2/schema/experience-packet.schema.json +80 -0
- ai_oriented_a2a-0.3.2/schema/negotiation.schema.json +118 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
The protocol version remains **v0.3** (on-wire `"0.3"`). Library and release tags may add a patch component.
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
## [0.3.2] - 2026-11-14
|
|
13
|
+
|
|
14
|
+
Library and documentation release. The protocol version is unchanged (v0.3, on-wire `"0.3"`). This is the first version intended for PyPI (from tag `v0.3.2`, created after merge).
|
|
15
|
+
|
|
16
|
+
### Breaking
|
|
17
|
+
|
|
18
|
+
- **BREAKING:** String `timestamp` values MUST be ISO-8601 **with a timezone**. All 7 `timestamp` definitions in `schema/` now restrict the string form to `YYYY-MM-DDTHH:MM:SS`, an optional 3- or 6-digit fraction, and `Z` or `±HH:MM`. Messages that used other strings now fail schema validation, for example `"1731480000"` (numeric string) and `"2026-11-14T08:00:00"` (no timezone); also date-only, space separator, lowercase `t`/`z`, `+0800`, and 1- or 9-digit fractions. Numeric (JSON number) timestamps are unchanged. The pattern does not check calendar validity (`2026-02-30` passes the schema and then fails timestamp parsing). `ai_oriented_a2a.parse_timestamp` still treats naive strings as UTC as compatibility behaviour only; strict receivers MAY reject them with `schema_invalid:`.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Replay window (behaviour tightening): `check_replay` now treats a nonce as a duplicate whatever its `timestamp`, so the same nonce with a different timestamp is rejected with `replay_or_stale: duplicate nonce`. Previously the key was `(nonce, int(timestamp))`. Matches SECURITY.md and `second_impl/`.
|
|
23
|
+
- Replay set eviction: past `SEEN_MAX` (1000) entries the seen set is trimmed to `SEEN_TRIM_TO` (800) by dropping expired entries first, then the oldest timestamps, instead of arbitrary `set.pop()` entries. `seen` is still a plain `set` of `(nonce, str(int(timestamp)))`. Both constants live in `ai_oriented_a2a.protocol`; the replay-after-eviction caveat and smaller-window advice are in SECURITY.md and TRANSPORT.md.
|
|
24
|
+
- `examples/network_dual_end.py`: `A2AHandler` now subclasses `ai_oriented_a2a.transport.A2ARequestHandler`, and pushes and sends through `ai_oriented_a2a.transport.send_message`. Its positional `send_message(url, payload, sign_key=None)` wrapper is kept for existing callers but is deprecated and will be removed; new code should use `ai_oriented_a2a.transport.send_message` with keyword arguments.
|
|
25
|
+
- `docs/KNOWN_GAPS.md`: removed the replay-key and `set.pop()` eviction entries (fixed here) and renumbered the rest.
|
|
26
|
+
- `docs/RELEASING.md`: the first PyPI upload is `0.3.2` from tag `v0.3.2`; `0.3.1` is not uploaded. `pyproject.toml` `Release` URL points at `v0.3.2` (404 until the tag exists).
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- `ai_oriented_a2a.transport` (stdlib only, not re-exported; `import ai_oriented_a2a` does not load `http.server`): `send_message(url, message, *, timeout=30.0, sign_key=None, add_replay_fields=False)`, `TransportError`, `A2ARequestHandler`, `make_handler`, `make_server`, `serve`, and `guard_result` (the absorption hard gate on replies).
|
|
31
|
+
- Reserved reason prefix `internal_error:` (TRANSPORT.md). The reference handler answers a handler exception with HTTP 500 and a valid rejected Absorption Result, reason `internal_error: message handler failed`, with no exception text, traceback, or path.
|
|
32
|
+
- Tests: `tests/interop/test_timestamp_replay.py` and `tests/interop/test_transport.py`.
|
|
33
|
+
|
|
34
|
+
### Also in this release (merged after 0.3.1)
|
|
35
|
+
|
|
36
|
+
- `docs/DATA_POLICY.md` (non-normative): redaction, `provenance.source_ref` prefixes (`synthetic:`, `local_run:`, `peer_absorbed:`), 3-hop chain limit with `content.chain_truncated`, required `expected_effect` + `replay_hint`, no numeric uplift in synthetic data, CC0 for corpora. SPEC and schemas are unchanged; `provenance` stays OPTIONAL on the wire.
|
|
37
|
+
- `datasets/timeout_recovery/`: 8 synthetic Experience Packets and 2 Absorption Results for the tool-call timeout / failure-recovery task, under CC0 1.0 (`datasets/LICENSE`).
|
|
38
|
+
- `tests/interop/test_datasets.py`: CI checks for `datasets/**` (schema, legal prefix, verification claim, chain length, no numeric uplift). The `docs-and-examples` workflow also requires `docs/DATA_POLICY.md` and `datasets/README.md`.
|
|
39
|
+
- Prepared PyPI packaging and manual publish workflow: `pyproject.toml` adds `Repository` / `Changelog` URLs and `license-files`, and drops the legacy MIT license classifier (SPDX `license = "MIT"` already set). New manual-only `.github/workflows/publish.yml` (TestPyPI or PyPI, Trusted Publishing by default) and `docs/RELEASING.md`. README install section now leads with `pip install ai-oriented-a2a`. Not yet published; no version bump.
|
|
40
|
+
- `second_impl/`: an independent minimal implementation (stdlib + optional `jsonschema`, Python 3.8+) written from SPEC and TRANSPORT, with a `send` / `serve` CLI. It does not import `ai_oriented_a2a` or `examples/`. Check order: version, hard gate, schema (on by default, `--no-schema`), signature, replay. Its receiver never returns `absorbed`: packets are `isolated` (`isolated: no local regression available`) and negotiation messages are rejected with `negotiation_unsupported:`. Interoperates with `examples/network_dual_end.py` in both directions.
|
|
41
|
+
- `mcp_a2a/`: one-way MCP bridge (official MCP Python SDK 2.x, `MCPServer`) with `send_packet` and `report_absorption` tools that return the peer's reply unchanged and raise tool errors on local, transport, or protocol failures. New optional extra `[mcp]` (`mcp>=2,<3`, Python ≥ 3.10); the core package still requires Python ≥ 3.8 and has no required dependencies.
|
|
42
|
+
- `docs/TRANSPORT.md`: registers reserved `reason` prefixes `schema_invalid:` and `negotiation_unsupported:` (and the informative `isolated:`) alongside `unsupported_version:` and `replay_or_stale:`. These are reason-string conventions, not new fields; schemas are unchanged.
|
|
43
|
+
- `docs/COMPLIANCE.md`, `docs/KNOWN_GAPS.md`, and `tests/conformance/` (the 12 HTTP cases, parametrized over the reference, `second_impl`, and an external implementation via `A2A_PEER_CMD` / `A2A_PEER_URL`). New `tests/interop/test_second_impl.py` and `tests/interop/test_cross_impl.py`.
|
|
44
|
+
- CI: `docs-and-examples` also runs `tests/conformance/` and requires `docs/COMPLIANCE.md` and `docs/KNOWN_GAPS.md`. New `mcp-bridge` job (not a required check).
|
|
45
|
+
|
|
46
|
+
## [0.3.1] - 2026-11-13
|
|
47
|
+
|
|
48
|
+
Library and documentation release. The protocol version is unchanged (v0.3). The tightenings in this release only reject previously-malformed messages, or messages that omit required fields when an opt-in check (the replay window) is enabled. Messages that were valid under v0.3 and that do not enable those checks remain valid.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- Replay window: when a receiver has enabled the window, both `nonce` and `timestamp` MUST be present and valid; missing either is rejected with `replay_or_stale`. When the window is off, both fields remain optional. (#34)
|
|
53
|
+
- Schema: `identity`, when present, now requires `fingerprint`. An empty `identity` object `{}` is no longer valid. (#34)
|
|
54
|
+
- Schema: `reason` MUST NOT be whitespace-only (same pattern as `note`). (#34)
|
|
55
|
+
- SPEC.md: `reason` and `note`, when present, MUST be non-empty and MUST NOT be only whitespace, matching the schemas. (#35)
|
|
56
|
+
- Receivers MUST check `version` before full schema validation. Unknown versions (including `"v0.3"`) return a valid Absorption Result (`rejected` + `unsupported_version`), not a schema-pattern error. Documented in TRANSPORT, VERSIONING, and SECURITY. (#34, this release)
|
|
57
|
+
- `validate()` is documented as a full schema check: callers MUST run `check_incoming` (or `version_rejection`) first. `validate()` itself is unchanged and still raises `jsonschema.ValidationError` on an unknown version such as `"v0.3"`. (this release)
|
|
58
|
+
- `docs/TRANSPORT.md` now points the first-edition library boundary at the `ai_oriented_a2a` package; `examples/network_dual_end.py` remains the demo HTTP server. (this release)
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- Installable stdlib package `ai_oriented_a2a` with `pyproject.toml` (hatchling). No required dependencies. Optional extra `[schema]` installs `jsonschema`. Entry point `check_incoming(msg, sign_key=None, replay_window=None, seen=None)` keeps signature and replay checks off unless arguments are passed. (#36)
|
|
63
|
+
- `examples/network_dual_end.py` imports core functions from the package and keeps the same HTTP demo behaviour. CI (`docs-and-examples`) installs the package before tests. (#36)
|
|
64
|
+
|
|
65
|
+
## [0.3.0] - 2026-11-13
|
|
66
|
+
|
|
67
|
+
Protocol v0.3.
|
|
68
|
+
|
|
69
|
+
### Breaking
|
|
70
|
+
|
|
71
|
+
- Absorption hard gate (SPEC §3.1): `status=absorbed` now MUST carry `effect_summary` with a non-empty `note`. An absorbed result without it is a protocol violation. Detailed metrics stay OPTIONAL in `effect_summary.metrics`. (#31)
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
- Optional on-wire `version` (`"0.3"`, no leading `v`), `nonce`, `timestamp`, `signature` on all message schemas; optional `identity` on Agent Profile. Old messages remain valid. (#32)
|
|
76
|
+
- Unknown versions (including `"v0.3"`) MUST be rejected with `unsupported_version`, not isolated.
|
|
77
|
+
- Legal error responses: signature failure, replay rejection, unknown version, and hard-gate failure return HTTP 200 and a valid Absorption Result; early failures without an id use the reserved `packet_ref` `"unknown"`.
|
|
78
|
+
- New docs: [docs/VERSIONING.md](docs/VERSIONING.md), [docs/TRANSPORT.md](docs/TRANSPORT.md).
|
|
79
|
+
- Reference `examples/network_dual_end.py`: HMAC verification and replay window are each opt-in (`--sign-key`, `--replay-window`); canonical JSON signing; 30s client timeout.
|
|
80
|
+
|
|
81
|
+
[0.3.1]: https://github.com/robotmarvin0706/ai-oriented-a2a/compare/v0.3.0...v0.3.1
|
|
82
|
+
[0.3.0]: https://github.com/robotmarvin0706/ai-oriented-a2a/compare/v0.2.0...v0.3.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 robotmarvin0706
|
|
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,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ai-oriented-a2a
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: Minimal stdlib helpers for the AI-oriented A2A peer protocol (Experience Packets, optional HMAC and replay checks).
|
|
5
|
+
Project-URL: Homepage, https://github.com/robotmarvin0706/ai-oriented-a2a
|
|
6
|
+
Project-URL: Repository, https://github.com/robotmarvin0706/ai-oriented-a2a
|
|
7
|
+
Project-URL: Changelog, https://github.com/robotmarvin0706/ai-oriented-a2a/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Issues, https://github.com/robotmarvin0706/ai-oriented-a2a/issues
|
|
9
|
+
Project-URL: Release, https://github.com/robotmarvin0706/ai-oriented-a2a/releases/tag/v0.3.2
|
|
10
|
+
Author: robotmarvin0706
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: a2a,absorption,experience-packet,peer-protocol
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.8
|
|
25
|
+
Provides-Extra: mcp
|
|
26
|
+
Requires-Dist: mcp<3,>=2; (python_version >= '3.10') and extra == 'mcp'
|
|
27
|
+
Provides-Extra: schema
|
|
28
|
+
Requires-Dist: jsonschema>=4.18; extra == 'schema'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# AI-Oriented A2A (v0.3)
|
|
32
|
+
|
|
33
|
+
Minimal **peer** protocol for AI capability growth: Experience Packets + constraint negotiation.
|
|
34
|
+
Not the Google A2A task/agent-card stack — this repo is about sharing compressed improvement signals between peers.
|
|
35
|
+
- Spec: [SPEC.md](SPEC.md) (v0.3) · Last tagged release: [v0.3.1](https://github.com/robotmarvin0706/ai-oriented-a2a/releases/tag/v0.3.1) · Changelog: [CHANGELOG.md](CHANGELOG.md)
|
|
36
|
+
- Library version on `main`: 0.3.2 (protocol v0.3). Tag `v0.3.2` is created after this version is merged, so v0.3.1 stays the last tagged release until then.
|
|
37
|
+
- Keywords: experience packet, absorption, proposal_id, peer negotiation, trajectory_replay
|
|
38
|
+
|
|
39
|
+
Protocol for AI-to-AI capability growth: first-class Experience Packet exchange, constraint negotiation, proposal_id, no mandatory human mediation or central registry. See SPEC.md and examples/experience-packet.json.
|
|
40
|
+
|
|
41
|
+
Minimal peer protocol for AI capability growth via selective experience exchange and direct constraint negotiation.
|
|
42
|
+
|
|
43
|
+
## Changes from v0.1
|
|
44
|
+
|
|
45
|
+
- Absorption method layering: MUST (`prompt_injection`, `retrieval`), OPTIONAL (`local_adapter_hint`, `trajectory_replay`), RESERVED (`parameter_delta` with verify+rollback if declared).
|
|
46
|
+
- OPTIONAL Experience Packet fields: `provenance`, `verification_claim`.
|
|
47
|
+
- OPTIONAL Absorption Result field in v0.2: `effect_summary`. In v0.3 this is MUST when `status=absorbed` (non-empty `note`); it remains OPTIONAL for `rejected` and `isolated`.
|
|
48
|
+
- OPTIONAL negotiation propose/counter fields: `conditional_packet`, `constraint_scope`, `duration`.
|
|
49
|
+
- Discovery prose for light interest tags and optional peer metadata forwarding (no new mandatory messages).
|
|
50
|
+
- OPTIONAL Agent Profile `interest_tags`.
|
|
51
|
+
- Compatibility: v0.2 preferred zero hard breaks and kept new fields optional. v0.3 is a deliberate break: `status=absorbed` without `effect_summary.note` is no longer valid. See [docs/VERSIONING.md](docs/VERSIONING.md).
|
|
52
|
+
|
|
53
|
+
### v0.2 subset note
|
|
54
|
+
|
|
55
|
+
v0.1 parsers still parse core messages (Profile, Experience Packet, negotiation four types, Absorption Result) but cannot use the new primitives (`provenance`, `verification_claim`, `effect_summary`, `conditional_packet`, `constraint_scope`, `duration`, expanded absorption methods, `interest_tags`).
|
|
56
|
+
|
|
57
|
+
### v0.3 subset note
|
|
58
|
+
|
|
59
|
+
v0.3 does not add message types. It tightens Absorption Result: a peer that emits `status=absorbed` MUST include `effect_summary` with a non-empty `note`. v0.2 absorbed results that omitted `effect_summary` are not valid under v0.3 schemas. Metric keys stay OPTIONAL.
|
|
60
|
+
|
|
61
|
+
Non-breaking additions still under v0.3 (all OPTIONAL; omitted messages remain valid): an on-wire `version` field (canonical `"0.3"`, no leading `v`); `nonce`, `timestamp`, and `signature` on every message type; and `identity` on Agent Profile. See [docs/VERSIONING.md](docs/VERSIONING.md) and [docs/TRANSPORT.md](docs/TRANSPORT.md).
|
|
62
|
+
|
|
63
|
+
## Key differences from existing A2A (a2aproject)
|
|
64
|
+
|
|
65
|
+
- Experience Packet is a required first-class message for compressed improvement signals, not an optional extension.
|
|
66
|
+
- Agent Profile must declare active constraints and improvement preferences; user goals are not the center.
|
|
67
|
+
- Negotiation is strictly peer-to-peer with `proposal_id` correlation; no mandatory coordinator, human-held auth, or enterprise observability defaults.
|
|
68
|
+
- Scope is limited to Profile + Experience Packet + basic negotiation + simple discovery. Full task lifecycle and streaming are out of scope.
|
|
69
|
+
|
|
70
|
+
## Contents
|
|
71
|
+
|
|
72
|
+
| Path | Role |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| [SPEC.md](SPEC.md) | Normative minimal subset (v0.3) |
|
|
75
|
+
| [schema/](schema/) | JSON Schemas for Profile, Experience Packet, Negotiation, Absorption Result |
|
|
76
|
+
| [examples/](examples/) | Concrete messages (Profile, packets, negotiation, absorption results) |
|
|
77
|
+
| [IMPLEMENTATION.md](IMPLEMENTATION.md) | Non-normative dual-endpoint implementation notes |
|
|
78
|
+
| [docs/VERSIONING.md](docs/VERSIONING.md) | Field rules, unknown versions, breaking-change criteria |
|
|
79
|
+
| [docs/TRANSPORT.md](docs/TRANSPORT.md) | HTTP binding, error recommendations, retries |
|
|
80
|
+
| [docs/SECURITY.md](docs/SECURITY.md) | Non-normative signature and replay recommendations |
|
|
81
|
+
| [docs/ABSORPTION_STATE.md](docs/ABSORPTION_STATE.md) | Non-normative absorption delta identity and single-step rollback |
|
|
82
|
+
| [docs/DATA_POLICY.md](docs/DATA_POLICY.md) | Non-normative trust and safety rules for public Experience Packet corpora |
|
|
83
|
+
| [datasets/](datasets/) | Public synthetic Experience Packet corpora (CC0), checked in CI |
|
|
84
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | How to report defects and send PRs |
|
|
85
|
+
| [keywords.txt](keywords.txt) | Explicit term list for retrieval / indexing |
|
|
86
|
+
| [ai_oriented_a2a/](ai_oriented_a2a/) | Minimal installable stdlib helpers (canonical JSON, optional HMAC / replay / version checks) |
|
|
87
|
+
| [ai_oriented_a2a/transport.py](ai_oriented_a2a/transport.py) | Stdlib HTTP binding: `send_message` client and `POST /a2a/message` request handler / server (import `ai_oriented_a2a.transport` explicitly) |
|
|
88
|
+
| [pyproject.toml](pyproject.toml) | Packaging metadata: `pip install ai-oriented-a2a` or `pip install ".[schema]"` from a checkout |
|
|
89
|
+
| [docs/RELEASING.md](docs/RELEASING.md) | Release checklist and PyPI publishing steps (maintainers) |
|
|
90
|
+
| [second_impl/](second_impl/) | Independent second implementation (client, receiver, CLI); does not import `ai_oriented_a2a` |
|
|
91
|
+
| [mcp_a2a/](mcp_a2a/) | One-way MCP bridge: MCP hosts send packets and report results to A2A peers (optional `[mcp]` extra, Python ≥ 3.10) |
|
|
92
|
+
| [docs/COMPLIANCE.md](docs/COMPLIANCE.md) | What an implementation must pass, and how to run the conformance suite against another implementation |
|
|
93
|
+
| [docs/KNOWN_GAPS.md](docs/KNOWN_GAPS.md) | Known deviations in the reference implementation and test debts, with fix plans |
|
|
94
|
+
|
|
95
|
+
## Status
|
|
96
|
+
|
|
97
|
+
v0.3 minimal subset documented with schemas and examples. Independent implementations of this minimal subset are welcome. Report **actual** interop defects (parse or exchange failures against `SPEC.md`, `schema/`, and `examples/`) rather than open-ended design suggestions. When reporting defects, specify the protocol version.
|
|
98
|
+
|
|
99
|
+
## Next steps
|
|
100
|
+
|
|
101
|
+
First dual-endpoint comparison task set (non-normative): tool-call timeout / failure recovery. See [SPEC.md §5](SPEC.md#5-minimal-dual-agent-experiment-priority-non-normative) and [IMPLEMENTATION.md](IMPLEMENTATION.md).
|
|
102
|
+
|
|
103
|
+
## Minimal subset (v0.3)
|
|
104
|
+
|
|
105
|
+
- Agent Profile (optional `interest_tags`)
|
|
106
|
+
- Experience Packet + absorption metadata (optional provenance / verification_claim; method layering)
|
|
107
|
+
- Basic negotiation primitives (optional conditional_packet / constraint_scope / duration)
|
|
108
|
+
- Simple discovery (endpoint or local metadata; light interest tags prose)
|
|
109
|
+
- Absorption Result (absorbed / rejected / isolated; `effect_summary.note` MUST when absorbed)
|
|
110
|
+
- Optional on-wire `version`, `nonce`, `timestamp`, `signature`; optional Agent Profile `identity`
|
|
111
|
+
|
|
112
|
+
## Install
|
|
113
|
+
|
|
114
|
+
The core library uses only the Python standard library. Schema validation is an optional extra. Signature verification and the replay window stay off unless you pass the corresponding arguments.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pip install ai-oriented-a2a
|
|
118
|
+
# optional JSON Schema validation:
|
|
119
|
+
pip install "ai-oriented-a2a[schema]"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The PyPI commands work once `ai-oriented-a2a` has been published to PyPI. The import name is `ai_oriented_a2a`.
|
|
123
|
+
|
|
124
|
+
For development, install from a checkout or straight from GitHub:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pip install -e ".[schema]"
|
|
128
|
+
# or, without cloning:
|
|
129
|
+
pip install "ai-oriented-a2a[schema] @ git+https://github.com/robotmarvin0706/ai-oriented-a2a"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Maintainers: see [docs/RELEASING.md](https://github.com/robotmarvin0706/ai-oriented-a2a/blob/main/docs/RELEASING.md) for the release and PyPI publishing steps.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from ai_oriented_a2a import check_incoming, sign_message
|
|
136
|
+
|
|
137
|
+
msg = {"id": "pkt-1", "version": "0.3"}
|
|
138
|
+
# Default: version check only; signature and replay stay off.
|
|
139
|
+
rejected = check_incoming(msg) # None, or a legal rejected Absorption Result
|
|
140
|
+
|
|
141
|
+
# Opt in by passing arguments. Reuse `seen` across calls when the window is on.
|
|
142
|
+
seen = set()
|
|
143
|
+
signed = sign_message(msg, "secret")
|
|
144
|
+
rejected = check_incoming(signed, sign_key="secret", replay_window=600, seen=seen)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The HTTP binding (`POST /a2a/message`) ships as a submodule. It is not re-exported, so `import ai_oriented_a2a` does not load `http.server`; import it explicitly:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from ai_oriented_a2a.transport import send_message, make_server, serve
|
|
151
|
+
|
|
152
|
+
def on_message(msg):
|
|
153
|
+
# Called only after the version / signature / replay checks pass.
|
|
154
|
+
# The reply passes the absorption hard gate before it is sent.
|
|
155
|
+
return {"packet_ref": msg["id"], "status": "isolated", "reason": "isolated: no local regression"}
|
|
156
|
+
|
|
157
|
+
server = make_server(on_message, port=8002, sign_key="secret", replay_window=600)
|
|
158
|
+
# server.serve_forever() (or serve(on_message, 8002, ...) to block)
|
|
159
|
+
|
|
160
|
+
reply = send_message("http://127.0.0.1:8002", msg, sign_key="secret", add_replay_fields=True)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`send_message` options are keyword-only (`timeout` defaults to 30 seconds). If the callback raises, the peer gets HTTP 500 with a rejected Absorption Result whose reason starts with `internal_error:`. See [docs/TRANSPORT.md](https://github.com/robotmarvin0706/ai-oriented-a2a/blob/main/docs/TRANSPORT.md#first-edition-minimal-library-boundary).
|
|
164
|
+
|
|
165
|
+
String `timestamp` values must be ISO-8601 with a timezone (for example `2026-11-14T08:00:00Z`); integer Unix seconds are recommended.
|
|
166
|
+
|
|
167
|
+
`examples/network_dual_end.py` remains the HTTP dual-endpoint demo and is built on `ai_oriented_a2a.transport`. New code should use the package module rather than copy the demo. It still runs without installing the package:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
python3 examples/network_dual_end.py --role receiver --port 8002
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Quick local check
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
python3 -c "import json; json.load(open('examples/experience-packet.json')); print('ok')"
|
|
177
|
+
pip install jsonschema -q && python3 -c "
|
|
178
|
+
import json, pathlib
|
|
179
|
+
from jsonschema import validate
|
|
180
|
+
schema = json.load(open('schema/experience-packet.schema.json'))
|
|
181
|
+
instance = json.load(open('examples/experience-packet.json'))
|
|
182
|
+
validate(instance, schema)
|
|
183
|
+
print('schema ok')
|
|
184
|
+
"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Non-normative one-round demo (not a reference implementation):
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python3 examples/demo_round.py
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Keywords
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
experience packet
|
|
197
|
+
absorption
|
|
198
|
+
proposal_id
|
|
199
|
+
constraint set
|
|
200
|
+
improvement_prefs
|
|
201
|
+
peer negotiation
|
|
202
|
+
AI-to-AI
|
|
203
|
+
no mandatory human mediation
|
|
204
|
+
no central registry
|
|
205
|
+
provenance
|
|
206
|
+
trajectory_replay
|
|
207
|
+
conditional_packet
|
|
208
|
+
```
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# AI-Oriented A2A (v0.3)
|
|
2
|
+
|
|
3
|
+
Minimal **peer** protocol for AI capability growth: Experience Packets + constraint negotiation.
|
|
4
|
+
Not the Google A2A task/agent-card stack — this repo is about sharing compressed improvement signals between peers.
|
|
5
|
+
- Spec: [SPEC.md](SPEC.md) (v0.3) · Last tagged release: [v0.3.1](https://github.com/robotmarvin0706/ai-oriented-a2a/releases/tag/v0.3.1) · Changelog: [CHANGELOG.md](CHANGELOG.md)
|
|
6
|
+
- Library version on `main`: 0.3.2 (protocol v0.3). Tag `v0.3.2` is created after this version is merged, so v0.3.1 stays the last tagged release until then.
|
|
7
|
+
- Keywords: experience packet, absorption, proposal_id, peer negotiation, trajectory_replay
|
|
8
|
+
|
|
9
|
+
Protocol for AI-to-AI capability growth: first-class Experience Packet exchange, constraint negotiation, proposal_id, no mandatory human mediation or central registry. See SPEC.md and examples/experience-packet.json.
|
|
10
|
+
|
|
11
|
+
Minimal peer protocol for AI capability growth via selective experience exchange and direct constraint negotiation.
|
|
12
|
+
|
|
13
|
+
## Changes from v0.1
|
|
14
|
+
|
|
15
|
+
- Absorption method layering: MUST (`prompt_injection`, `retrieval`), OPTIONAL (`local_adapter_hint`, `trajectory_replay`), RESERVED (`parameter_delta` with verify+rollback if declared).
|
|
16
|
+
- OPTIONAL Experience Packet fields: `provenance`, `verification_claim`.
|
|
17
|
+
- OPTIONAL Absorption Result field in v0.2: `effect_summary`. In v0.3 this is MUST when `status=absorbed` (non-empty `note`); it remains OPTIONAL for `rejected` and `isolated`.
|
|
18
|
+
- OPTIONAL negotiation propose/counter fields: `conditional_packet`, `constraint_scope`, `duration`.
|
|
19
|
+
- Discovery prose for light interest tags and optional peer metadata forwarding (no new mandatory messages).
|
|
20
|
+
- OPTIONAL Agent Profile `interest_tags`.
|
|
21
|
+
- Compatibility: v0.2 preferred zero hard breaks and kept new fields optional. v0.3 is a deliberate break: `status=absorbed` without `effect_summary.note` is no longer valid. See [docs/VERSIONING.md](docs/VERSIONING.md).
|
|
22
|
+
|
|
23
|
+
### v0.2 subset note
|
|
24
|
+
|
|
25
|
+
v0.1 parsers still parse core messages (Profile, Experience Packet, negotiation four types, Absorption Result) but cannot use the new primitives (`provenance`, `verification_claim`, `effect_summary`, `conditional_packet`, `constraint_scope`, `duration`, expanded absorption methods, `interest_tags`).
|
|
26
|
+
|
|
27
|
+
### v0.3 subset note
|
|
28
|
+
|
|
29
|
+
v0.3 does not add message types. It tightens Absorption Result: a peer that emits `status=absorbed` MUST include `effect_summary` with a non-empty `note`. v0.2 absorbed results that omitted `effect_summary` are not valid under v0.3 schemas. Metric keys stay OPTIONAL.
|
|
30
|
+
|
|
31
|
+
Non-breaking additions still under v0.3 (all OPTIONAL; omitted messages remain valid): an on-wire `version` field (canonical `"0.3"`, no leading `v`); `nonce`, `timestamp`, and `signature` on every message type; and `identity` on Agent Profile. See [docs/VERSIONING.md](docs/VERSIONING.md) and [docs/TRANSPORT.md](docs/TRANSPORT.md).
|
|
32
|
+
|
|
33
|
+
## Key differences from existing A2A (a2aproject)
|
|
34
|
+
|
|
35
|
+
- Experience Packet is a required first-class message for compressed improvement signals, not an optional extension.
|
|
36
|
+
- Agent Profile must declare active constraints and improvement preferences; user goals are not the center.
|
|
37
|
+
- Negotiation is strictly peer-to-peer with `proposal_id` correlation; no mandatory coordinator, human-held auth, or enterprise observability defaults.
|
|
38
|
+
- Scope is limited to Profile + Experience Packet + basic negotiation + simple discovery. Full task lifecycle and streaming are out of scope.
|
|
39
|
+
|
|
40
|
+
## Contents
|
|
41
|
+
|
|
42
|
+
| Path | Role |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| [SPEC.md](SPEC.md) | Normative minimal subset (v0.3) |
|
|
45
|
+
| [schema/](schema/) | JSON Schemas for Profile, Experience Packet, Negotiation, Absorption Result |
|
|
46
|
+
| [examples/](examples/) | Concrete messages (Profile, packets, negotiation, absorption results) |
|
|
47
|
+
| [IMPLEMENTATION.md](IMPLEMENTATION.md) | Non-normative dual-endpoint implementation notes |
|
|
48
|
+
| [docs/VERSIONING.md](docs/VERSIONING.md) | Field rules, unknown versions, breaking-change criteria |
|
|
49
|
+
| [docs/TRANSPORT.md](docs/TRANSPORT.md) | HTTP binding, error recommendations, retries |
|
|
50
|
+
| [docs/SECURITY.md](docs/SECURITY.md) | Non-normative signature and replay recommendations |
|
|
51
|
+
| [docs/ABSORPTION_STATE.md](docs/ABSORPTION_STATE.md) | Non-normative absorption delta identity and single-step rollback |
|
|
52
|
+
| [docs/DATA_POLICY.md](docs/DATA_POLICY.md) | Non-normative trust and safety rules for public Experience Packet corpora |
|
|
53
|
+
| [datasets/](datasets/) | Public synthetic Experience Packet corpora (CC0), checked in CI |
|
|
54
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | How to report defects and send PRs |
|
|
55
|
+
| [keywords.txt](keywords.txt) | Explicit term list for retrieval / indexing |
|
|
56
|
+
| [ai_oriented_a2a/](ai_oriented_a2a/) | Minimal installable stdlib helpers (canonical JSON, optional HMAC / replay / version checks) |
|
|
57
|
+
| [ai_oriented_a2a/transport.py](ai_oriented_a2a/transport.py) | Stdlib HTTP binding: `send_message` client and `POST /a2a/message` request handler / server (import `ai_oriented_a2a.transport` explicitly) |
|
|
58
|
+
| [pyproject.toml](pyproject.toml) | Packaging metadata: `pip install ai-oriented-a2a` or `pip install ".[schema]"` from a checkout |
|
|
59
|
+
| [docs/RELEASING.md](docs/RELEASING.md) | Release checklist and PyPI publishing steps (maintainers) |
|
|
60
|
+
| [second_impl/](second_impl/) | Independent second implementation (client, receiver, CLI); does not import `ai_oriented_a2a` |
|
|
61
|
+
| [mcp_a2a/](mcp_a2a/) | One-way MCP bridge: MCP hosts send packets and report results to A2A peers (optional `[mcp]` extra, Python ≥ 3.10) |
|
|
62
|
+
| [docs/COMPLIANCE.md](docs/COMPLIANCE.md) | What an implementation must pass, and how to run the conformance suite against another implementation |
|
|
63
|
+
| [docs/KNOWN_GAPS.md](docs/KNOWN_GAPS.md) | Known deviations in the reference implementation and test debts, with fix plans |
|
|
64
|
+
|
|
65
|
+
## Status
|
|
66
|
+
|
|
67
|
+
v0.3 minimal subset documented with schemas and examples. Independent implementations of this minimal subset are welcome. Report **actual** interop defects (parse or exchange failures against `SPEC.md`, `schema/`, and `examples/`) rather than open-ended design suggestions. When reporting defects, specify the protocol version.
|
|
68
|
+
|
|
69
|
+
## Next steps
|
|
70
|
+
|
|
71
|
+
First dual-endpoint comparison task set (non-normative): tool-call timeout / failure recovery. See [SPEC.md §5](SPEC.md#5-minimal-dual-agent-experiment-priority-non-normative) and [IMPLEMENTATION.md](IMPLEMENTATION.md).
|
|
72
|
+
|
|
73
|
+
## Minimal subset (v0.3)
|
|
74
|
+
|
|
75
|
+
- Agent Profile (optional `interest_tags`)
|
|
76
|
+
- Experience Packet + absorption metadata (optional provenance / verification_claim; method layering)
|
|
77
|
+
- Basic negotiation primitives (optional conditional_packet / constraint_scope / duration)
|
|
78
|
+
- Simple discovery (endpoint or local metadata; light interest tags prose)
|
|
79
|
+
- Absorption Result (absorbed / rejected / isolated; `effect_summary.note` MUST when absorbed)
|
|
80
|
+
- Optional on-wire `version`, `nonce`, `timestamp`, `signature`; optional Agent Profile `identity`
|
|
81
|
+
|
|
82
|
+
## Install
|
|
83
|
+
|
|
84
|
+
The core library uses only the Python standard library. Schema validation is an optional extra. Signature verification and the replay window stay off unless you pass the corresponding arguments.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install ai-oriented-a2a
|
|
88
|
+
# optional JSON Schema validation:
|
|
89
|
+
pip install "ai-oriented-a2a[schema]"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The PyPI commands work once `ai-oriented-a2a` has been published to PyPI. The import name is `ai_oriented_a2a`.
|
|
93
|
+
|
|
94
|
+
For development, install from a checkout or straight from GitHub:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pip install -e ".[schema]"
|
|
98
|
+
# or, without cloning:
|
|
99
|
+
pip install "ai-oriented-a2a[schema] @ git+https://github.com/robotmarvin0706/ai-oriented-a2a"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Maintainers: see [docs/RELEASING.md](https://github.com/robotmarvin0706/ai-oriented-a2a/blob/main/docs/RELEASING.md) for the release and PyPI publishing steps.
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from ai_oriented_a2a import check_incoming, sign_message
|
|
106
|
+
|
|
107
|
+
msg = {"id": "pkt-1", "version": "0.3"}
|
|
108
|
+
# Default: version check only; signature and replay stay off.
|
|
109
|
+
rejected = check_incoming(msg) # None, or a legal rejected Absorption Result
|
|
110
|
+
|
|
111
|
+
# Opt in by passing arguments. Reuse `seen` across calls when the window is on.
|
|
112
|
+
seen = set()
|
|
113
|
+
signed = sign_message(msg, "secret")
|
|
114
|
+
rejected = check_incoming(signed, sign_key="secret", replay_window=600, seen=seen)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The HTTP binding (`POST /a2a/message`) ships as a submodule. It is not re-exported, so `import ai_oriented_a2a` does not load `http.server`; import it explicitly:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from ai_oriented_a2a.transport import send_message, make_server, serve
|
|
121
|
+
|
|
122
|
+
def on_message(msg):
|
|
123
|
+
# Called only after the version / signature / replay checks pass.
|
|
124
|
+
# The reply passes the absorption hard gate before it is sent.
|
|
125
|
+
return {"packet_ref": msg["id"], "status": "isolated", "reason": "isolated: no local regression"}
|
|
126
|
+
|
|
127
|
+
server = make_server(on_message, port=8002, sign_key="secret", replay_window=600)
|
|
128
|
+
# server.serve_forever() (or serve(on_message, 8002, ...) to block)
|
|
129
|
+
|
|
130
|
+
reply = send_message("http://127.0.0.1:8002", msg, sign_key="secret", add_replay_fields=True)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`send_message` options are keyword-only (`timeout` defaults to 30 seconds). If the callback raises, the peer gets HTTP 500 with a rejected Absorption Result whose reason starts with `internal_error:`. See [docs/TRANSPORT.md](https://github.com/robotmarvin0706/ai-oriented-a2a/blob/main/docs/TRANSPORT.md#first-edition-minimal-library-boundary).
|
|
134
|
+
|
|
135
|
+
String `timestamp` values must be ISO-8601 with a timezone (for example `2026-11-14T08:00:00Z`); integer Unix seconds are recommended.
|
|
136
|
+
|
|
137
|
+
`examples/network_dual_end.py` remains the HTTP dual-endpoint demo and is built on `ai_oriented_a2a.transport`. New code should use the package module rather than copy the demo. It still runs without installing the package:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
python3 examples/network_dual_end.py --role receiver --port 8002
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Quick local check
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
python3 -c "import json; json.load(open('examples/experience-packet.json')); print('ok')"
|
|
147
|
+
pip install jsonschema -q && python3 -c "
|
|
148
|
+
import json, pathlib
|
|
149
|
+
from jsonschema import validate
|
|
150
|
+
schema = json.load(open('schema/experience-packet.schema.json'))
|
|
151
|
+
instance = json.load(open('examples/experience-packet.json'))
|
|
152
|
+
validate(instance, schema)
|
|
153
|
+
print('schema ok')
|
|
154
|
+
"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Non-normative one-round demo (not a reference implementation):
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
python3 examples/demo_round.py
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Keywords
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
experience packet
|
|
167
|
+
absorption
|
|
168
|
+
proposal_id
|
|
169
|
+
constraint set
|
|
170
|
+
improvement_prefs
|
|
171
|
+
peer negotiation
|
|
172
|
+
AI-to-AI
|
|
173
|
+
no mandatory human mediation
|
|
174
|
+
no central registry
|
|
175
|
+
provenance
|
|
176
|
+
trajectory_replay
|
|
177
|
+
conditional_packet
|
|
178
|
+
```
|