awp-python 0.1.0a2__tar.gz → 0.1.0a4__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.
Files changed (108) hide show
  1. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/CHANGELOG.md +18 -0
  2. awp_python-0.1.0a4/PKG-INFO +130 -0
  3. awp_python-0.1.0a4/README.md +109 -0
  4. awp_python-0.1.0a4/conformance/README.md +53 -0
  5. awp_python-0.1.0a4/conformance/core-agent-lockstep.json +1496 -0
  6. awp_python-0.1.0a4/conformance/core-agent-streaming.json +1498 -0
  7. awp_python-0.1.0a4/conformance/frames.json +4 -0
  8. awp_python-0.1.0a4/conformance/manifest-lockstep.json +157 -0
  9. awp_python-0.1.0a4/conformance/manifest-streaming.json +160 -0
  10. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/pyproject.toml +5 -6
  11. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/__init__.py +1 -1
  12. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/action-status.schema.json +1 -1
  13. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/action-submit-result.schema.json +1 -0
  14. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/approval-respond.schema.json +4 -4
  15. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/common.schema.json +3 -3
  16. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/error.schema.json +1 -1
  17. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/frame-inline.schema.json +1 -1
  18. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/obs-report.schema.json +1 -1
  19. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/safety-policy.schema.json +1 -0
  20. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-ready.schema.json +2 -2
  21. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-state.schema.json +1 -1
  22. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/world-event.schema.json +1 -1
  23. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/aio.py +45 -10
  24. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/client.py +62 -10
  25. awp_python-0.1.0a4/src/awp/demo.py +157 -0
  26. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/frames.py +4 -0
  27. awp_python-0.1.0a4/tests/test_aio.py +190 -0
  28. awp_python-0.1.0a4/tests/test_client.py +31 -0
  29. awp_python-0.1.0a4/tests/test_evidence.py +43 -0
  30. awp_python-0.1.0a4/tests/world.py +348 -0
  31. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/uv.lock +1 -1
  32. awp_python-0.1.0a2/PKG-INFO +0 -129
  33. awp_python-0.1.0a2/README.md +0 -108
  34. awp_python-0.1.0a2/conformance/README.md +0 -63
  35. awp_python-0.1.0a2/conformance/core-world-lockstep.json +0 -1655
  36. awp_python-0.1.0a2/conformance/core-world-streaming.json +0 -1657
  37. awp_python-0.1.0a2/scripts/check_traces.py +0 -57
  38. awp_python-0.1.0a2/src/awp_sim/__init__.py +0 -8
  39. awp_python-0.1.0a2/src/awp_sim/__main__.py +0 -5
  40. awp_python-0.1.0a2/src/awp_sim/arm.py +0 -177
  41. awp_python-0.1.0a2/src/awp_sim/audit.py +0 -138
  42. awp_python-0.1.0a2/src/awp_sim/cli.py +0 -238
  43. awp_python-0.1.0a2/src/awp_sim/config.py +0 -225
  44. awp_python-0.1.0a2/src/awp_sim/demo.py +0 -85
  45. awp_python-0.1.0a2/src/awp_sim/loopback.py +0 -222
  46. awp_python-0.1.0a2/src/awp_sim/py.typed +0 -0
  47. awp_python-0.1.0a2/src/awp_sim/recorder.py +0 -72
  48. awp_python-0.1.0a2/src/awp_sim/replay.py +0 -134
  49. awp_python-0.1.0a2/src/awp_sim/scenarios.py +0 -427
  50. awp_python-0.1.0a2/src/awp_sim/server.py +0 -336
  51. awp_python-0.1.0a2/src/awp_sim/session.py +0 -153
  52. awp_python-0.1.0a2/src/awp_sim/world.py +0 -1638
  53. awp_python-0.1.0a2/tests/helpers.py +0 -62
  54. awp_python-0.1.0a2/tests/test_audit.py +0 -62
  55. awp_python-0.1.0a2/tests/test_cli.py +0 -26
  56. awp_python-0.1.0a2/tests/test_e2e.py +0 -118
  57. awp_python-0.1.0a2/tests/test_evidence.py +0 -181
  58. awp_python-0.1.0a2/tests/test_features.py +0 -297
  59. awp_python-0.1.0a2/tests/test_regressions.py +0 -243
  60. awp_python-0.1.0a2/tests/test_scenarios.py +0 -33
  61. awp_python-0.1.0a2/tests/test_streams.py +0 -139
  62. awp_python-0.1.0a2/tests/test_world.py +0 -479
  63. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/.gitignore +0 -0
  64. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/.gitmodules +0 -0
  65. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/.python-version +0 -0
  66. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/LICENSE +0 -0
  67. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/scripts/sync_spec.py +0 -0
  68. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/lifecycle.json +0 -0
  69. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/action-cancel-result.schema.json +0 -0
  70. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/action-ref.schema.json +0 -0
  71. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/action-schema.schema.json +0 -0
  72. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/action-submit.schema.json +0 -0
  73. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/agent-manifest.schema.json +0 -0
  74. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/approval-requested.schema.json +0 -0
  75. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/embodiment.schema.json +0 -0
  76. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/empty-result.schema.json +0 -0
  77. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/frame-tree.schema.json +0 -0
  78. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/observation-channel.schema.json +0 -0
  79. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/ping-result.schema.json +0 -0
  80. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/ping.schema.json +0 -0
  81. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/profiles/gui-actions.schema.json +0 -0
  82. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/reset-result.schema.json +0 -0
  83. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/reset.schema.json +0 -0
  84. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/restore.schema.json +0 -0
  85. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-open.schema.json +0 -0
  86. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-resume.schema.json +0 -0
  87. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-telemetry.schema.json +0 -0
  88. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-transfer-result.schema.json +0 -0
  89. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/session-transfer.schema.json +0 -0
  90. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/snapshot-result.schema.json +0 -0
  91. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/subscribe-result.schema.json +0 -0
  92. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/subscribe.schema.json +0 -0
  93. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/task-update.schema.json +0 -0
  94. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/tick-result.schema.json +0 -0
  95. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/tick.schema.json +0 -0
  96. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/unsubscribe.schema.json +0 -0
  97. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/_spec/schemas/world-manifest.schema.json +0 -0
  98. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/clock.py +0 -0
  99. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/errors.py +0 -0
  100. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/jsonrpc.py +0 -0
  101. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/lifecycle.py +0 -0
  102. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/py.typed +0 -0
  103. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/src/awp/schema.py +0 -0
  104. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/tests/__init__.py +0 -0
  105. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/tests/conftest.py +0 -0
  106. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/tests/test_client_traces.py +0 -0
  107. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/tests/test_frames.py +0 -0
  108. {awp_python-0.1.0a2 → awp_python-0.1.0a4}/tests/test_schema.py +0 -0
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0a4
4
+
5
+ Targets specification revision `0.1-draft.9`.
6
+
7
+ - The reference world moves to its own package, [awp-sim](https://github.com/Hyperduality/awp-sim), and awp-python is the agent SDK alone.
8
+ - `awp-sim demo` becomes `awp-demo` (`awp.demo`). It reads `$AWP_URL` and `$AWP_TOKEN` when its flags are absent.
9
+ - Tests run against a scripted world over WebSockets instead of awp-sim, and CI runs awp-conformance against `awp-demo` in both time models.
10
+
11
+ ## 0.1.0a3
12
+
13
+ Targets specification revision `0.1-draft.9`.
14
+
15
+ - `awp_sim`: standing approvals (AWP-APR-004), declared as `safety_policy.standing_approvals` with the approval feature; a submission within a grant is admitted without approval and its result names the grant's `approval_id`.
16
+ - `awp`: `AsyncClient.advance` returns once every subscribed per-tick channel holds a frame of the new tick, which on a stream connection may follow the result (AWP-TIM-003). A `session.resume` answered `AWP_SESSION_UNKNOWN` closes the session and forgets its actions (AWP-SES-008). `respond_approval` takes `standing`.
17
+ - `awp-sim demo` resumes after a lost connection, or opens a new session if the world no longer holds it.
18
+ - `awp_sim`: an integer beyond 2^53-1 closes the session with reason `protocol_error` and the connection with code 1002 (AWP-CTL-009); a malformed frame on a stream connection closes it with code 1002 and `AWP_MALFORMED` (AWP-DAT-010); after a lockstep resumption every per-tick channel restarts with a resync keyframe at the current tick (AWP-TIM-009); after a reset the fresh frames precede the result (AWP-PRM-006).
19
+ - `awp`: an integer beyond 2^53-1 ends the session with `session.close` and close code 1002; a malformed stream frame is dropped and its stream connection closed and re-established; frames with `resync` but not `keyframe` are malformed. While a lost stream connection is down, `AsyncClient.command` raises instead of sending inline (AWP-TRN-010). `ClientConnection.receive_frame` raises for a malformed frame, and `delivery()` reports each channel's frames and gaps.
20
+
3
21
  ## 0.1.0a2
4
22
 
5
23
  Targets specification revision `0.1-draft.8`.
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.5
2
+ Name: awp-python
3
+ Version: 0.1.0a4
4
+ Summary: Agent World Protocol agent SDK for Python.
5
+ Project-URL: Specification, https://www.agentworldprotocol.com
6
+ Project-URL: Source, https://github.com/Hyperduality/awp-python
7
+ Author: Hyperduality
8
+ License-Expression: Apache-2.0
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Classifier: Typing :: Typed
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: jsonschema>=4.23
19
+ Requires-Dist: websockets>=13.0
20
+ Description-Content-Type: text/markdown
21
+
22
+ # awp-python
23
+
24
+ The Python agent SDK for the [Agent World Protocol](https://www.agentworldprotocol.com). `ClientConnection` is the agent side of AWP as a sans-IO state machine, and `awp.aio.AsyncClient` drives it over a WebSocket.
25
+
26
+ It targets specification revision **`0.1-draft.9`**, pinned as the `spec/` submodule. This is an alpha, so the API will change along with the draft. The reference world, [awp-sim](https://github.com/Hyperduality/awp-sim), is a separate package built on this one.
27
+
28
+ ## Status
29
+
30
+ ![AWP: Core Agent, AWP-conformant against 0.1-draft.9](https://img.shields.io/badge/AWP-Core_Agent%2C_conformant_0.1--draft.9-555)
31
+
32
+ In both time models, the demo agent built on the client is **Core Agent: AWP-conformant against 0.1-draft.9**. [awp-conformance](https://github.com/Hyperduality/awp-conformance) reports no failure and nothing untested, and [`conformance/`](conformance/README.md) holds the reports and the evidence for their manual rows. CI runs the suite against the demo agent on every change.
33
+
34
+ | Implemented | Not implemented |
35
+ |---|---|
36
+ | Lockstep and streaming sessions; `world.tick` advances that wait for every per-tick channel | Multi-bind (`embodiments`) |
37
+ | Inline and `ws` stream bindings; binary frame codec (every spec vector) | Other stream bindings (`webrtc`, `webtransport`, `shm`, `grpc`) |
38
+ | Action lifecycle checked against the spec's transition table; idempotent resubmission | |
39
+ | Heartbeats, clock synchronization, receiver reports, resumption with replay and acknowledgement | |
40
+ | Canonical schema validation in receiver and sender forms | |
41
+ | Task, approval and standing approvals, transfer, reset, snapshots, and command channels | |
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install --pre awp-python
47
+ ```
48
+
49
+ Requires Python 3.11+.
50
+
51
+ ## Using the client
52
+
53
+ With asyncio:
54
+
55
+ ```python
56
+ from awp import ClientConnection
57
+ from awp.aio import AsyncClient
58
+
59
+ conn = ClientConnection({"name": "my-agent", "version": "0.1.0", "vendor": "me"}, ["proprio/json"])
60
+ async with AsyncClient(conn, "ws://127.0.0.1:8710") as client:
61
+ await client.initialize()
62
+ await client.open_session("streaming", embodiment="arm_01", subscribe=["proprio"])
63
+ await client.wait_for(lambda e: "proprio" in client.latest)
64
+ record = await client.submit(
65
+ "move_to_pose",
66
+ {"pose": {"frame": "base", "p_m": [0.3, 0.2, 0.5], "q": [0, 0, 0, 1]}},
67
+ basis=client.latest["proprio"].frame, # the observation this intent rests on
68
+ valid_for_ms=200,
69
+ )
70
+ print((await client.wait_terminal(record.action_id)).state)
71
+ await client.close_session()
72
+ ```
73
+
74
+ Without asyncio, feed `ClientConnection` the decoded messages and send whatever it queues:
75
+
76
+ ```python
77
+ events = conn.receive(message) # typed events: ActionUpdated, FrameReceived, ...
78
+ for out in conn.outgoing(): # messages to send, in order
79
+ transport.send(json.dumps(out))
80
+ ```
81
+
82
+ The connection:
83
+
84
+ - tracks the action lifecycle against the spec's transition table;
85
+ - deduplicates replayed statuses;
86
+ - keeps the clock offset from heartbeats;
87
+ - reports any violation by the world as a `ProtocolViolation` event.
88
+
89
+ ## The demo agent
90
+
91
+ `awp-demo` is a scripted agent for awp-sim's arm. It moves, cancels a move, and triggers an envelope refusal. It rides out a lost connection by resuming the session, or by opening a new one if the world no longer holds it.
92
+
93
+ ```bash
94
+ pip install --pre awp-sim
95
+ awp-sim serve & # streaming world on ws://127.0.0.1:8710
96
+ awp-demo # or --url, --token ($AWP_URL, $AWP_TOKEN)
97
+ ```
98
+
99
+ ## Layout
100
+
101
+ ```
102
+ src/awp/ client protocol layer (sans-IO), asyncio adapter, frame codec, schemas, demo agent
103
+ src/awp/_spec/ schemas and lifecycle table bundled from spec/ (scripts/sync_spec.py)
104
+ tests/ unit tests, and a scripted world that serves over WebSockets
105
+ conformance/ conformance reports, the manifests they were run against, and evidence
106
+ spec/ agent-world-protocol, pinned at spec-v0.1-draft.9
107
+ ```
108
+
109
+ ## Development
110
+
111
+ ```bash
112
+ git clone --recurse-submodules https://github.com/Hyperduality/awp-python
113
+ cd awp-python
114
+ uv sync
115
+ uv run ruff check && uv run ruff format --check
116
+ uv run mypy
117
+ uv run pytest --cov
118
+ uv run python scripts/sync_spec.py --check
119
+ ```
120
+
121
+ To move to a new draft revision:
122
+
123
+ 1. Check out its tag in `spec/`.
124
+ 2. Run `scripts/sync_spec.py`.
125
+ 3. Update `SPEC_REVISION` in `src/awp/__init__.py`.
126
+ 4. Fix whatever the tests report.
127
+
128
+ ## License
129
+
130
+ Apache-2.0. See [LICENSE](LICENSE).
@@ -0,0 +1,109 @@
1
+ # awp-python
2
+
3
+ The Python agent SDK for the [Agent World Protocol](https://www.agentworldprotocol.com). `ClientConnection` is the agent side of AWP as a sans-IO state machine, and `awp.aio.AsyncClient` drives it over a WebSocket.
4
+
5
+ It targets specification revision **`0.1-draft.9`**, pinned as the `spec/` submodule. This is an alpha, so the API will change along with the draft. The reference world, [awp-sim](https://github.com/Hyperduality/awp-sim), is a separate package built on this one.
6
+
7
+ ## Status
8
+
9
+ ![AWP: Core Agent, AWP-conformant against 0.1-draft.9](https://img.shields.io/badge/AWP-Core_Agent%2C_conformant_0.1--draft.9-555)
10
+
11
+ In both time models, the demo agent built on the client is **Core Agent: AWP-conformant against 0.1-draft.9**. [awp-conformance](https://github.com/Hyperduality/awp-conformance) reports no failure and nothing untested, and [`conformance/`](conformance/README.md) holds the reports and the evidence for their manual rows. CI runs the suite against the demo agent on every change.
12
+
13
+ | Implemented | Not implemented |
14
+ |---|---|
15
+ | Lockstep and streaming sessions; `world.tick` advances that wait for every per-tick channel | Multi-bind (`embodiments`) |
16
+ | Inline and `ws` stream bindings; binary frame codec (every spec vector) | Other stream bindings (`webrtc`, `webtransport`, `shm`, `grpc`) |
17
+ | Action lifecycle checked against the spec's transition table; idempotent resubmission | |
18
+ | Heartbeats, clock synchronization, receiver reports, resumption with replay and acknowledgement | |
19
+ | Canonical schema validation in receiver and sender forms | |
20
+ | Task, approval and standing approvals, transfer, reset, snapshots, and command channels | |
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pip install --pre awp-python
26
+ ```
27
+
28
+ Requires Python 3.11+.
29
+
30
+ ## Using the client
31
+
32
+ With asyncio:
33
+
34
+ ```python
35
+ from awp import ClientConnection
36
+ from awp.aio import AsyncClient
37
+
38
+ conn = ClientConnection({"name": "my-agent", "version": "0.1.0", "vendor": "me"}, ["proprio/json"])
39
+ async with AsyncClient(conn, "ws://127.0.0.1:8710") as client:
40
+ await client.initialize()
41
+ await client.open_session("streaming", embodiment="arm_01", subscribe=["proprio"])
42
+ await client.wait_for(lambda e: "proprio" in client.latest)
43
+ record = await client.submit(
44
+ "move_to_pose",
45
+ {"pose": {"frame": "base", "p_m": [0.3, 0.2, 0.5], "q": [0, 0, 0, 1]}},
46
+ basis=client.latest["proprio"].frame, # the observation this intent rests on
47
+ valid_for_ms=200,
48
+ )
49
+ print((await client.wait_terminal(record.action_id)).state)
50
+ await client.close_session()
51
+ ```
52
+
53
+ Without asyncio, feed `ClientConnection` the decoded messages and send whatever it queues:
54
+
55
+ ```python
56
+ events = conn.receive(message) # typed events: ActionUpdated, FrameReceived, ...
57
+ for out in conn.outgoing(): # messages to send, in order
58
+ transport.send(json.dumps(out))
59
+ ```
60
+
61
+ The connection:
62
+
63
+ - tracks the action lifecycle against the spec's transition table;
64
+ - deduplicates replayed statuses;
65
+ - keeps the clock offset from heartbeats;
66
+ - reports any violation by the world as a `ProtocolViolation` event.
67
+
68
+ ## The demo agent
69
+
70
+ `awp-demo` is a scripted agent for awp-sim's arm. It moves, cancels a move, and triggers an envelope refusal. It rides out a lost connection by resuming the session, or by opening a new one if the world no longer holds it.
71
+
72
+ ```bash
73
+ pip install --pre awp-sim
74
+ awp-sim serve & # streaming world on ws://127.0.0.1:8710
75
+ awp-demo # or --url, --token ($AWP_URL, $AWP_TOKEN)
76
+ ```
77
+
78
+ ## Layout
79
+
80
+ ```
81
+ src/awp/ client protocol layer (sans-IO), asyncio adapter, frame codec, schemas, demo agent
82
+ src/awp/_spec/ schemas and lifecycle table bundled from spec/ (scripts/sync_spec.py)
83
+ tests/ unit tests, and a scripted world that serves over WebSockets
84
+ conformance/ conformance reports, the manifests they were run against, and evidence
85
+ spec/ agent-world-protocol, pinned at spec-v0.1-draft.9
86
+ ```
87
+
88
+ ## Development
89
+
90
+ ```bash
91
+ git clone --recurse-submodules https://github.com/Hyperduality/awp-python
92
+ cd awp-python
93
+ uv sync
94
+ uv run ruff check && uv run ruff format --check
95
+ uv run mypy
96
+ uv run pytest --cov
97
+ uv run python scripts/sync_spec.py --check
98
+ ```
99
+
100
+ To move to a new draft revision:
101
+
102
+ 1. Check out its tag in `spec/`.
103
+ 2. Run `scripts/sync_spec.py`.
104
+ 3. Update `SPEC_REVISION` in `src/awp/__init__.py`.
105
+ 4. Fix whatever the tests report.
106
+
107
+ ## License
108
+
109
+ Apache-2.0. See [LICENSE](LICENSE).
@@ -0,0 +1,53 @@
1
+ # Conformance
2
+
3
+ ![AWP: Core Agent, AWP-conformant against 0.1-draft.9](https://img.shields.io/badge/AWP-Core_Agent%2C_conformant_0.1--draft.9-555)
4
+
5
+ | Class | Configuration | Claim | Report |
6
+ |---|---|---|---|
7
+ | Core Agent | `awp-demo`, [`manifest-lockstep.json`](manifest-lockstep.json) | Core Agent (lockstep): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`core-agent-lockstep.json`](core-agent-lockstep.json) |
8
+ | Core Agent | `awp-demo`, [`manifest-streaming.json`](manifest-streaming.json) | Core Agent (streaming): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a3) | [`core-agent-streaming.json`](core-agent-streaming.json) |
9
+
10
+ The reports come from awp-conformance 0.1.0a3 run against awp-python 0.1.0a4. Neither has a failure or anything untested. The evidence for their `manual` rows is below (AWP-CNF-005).
11
+
12
+ ## Reproduce
13
+
14
+ The suite serves each manifest from its harness world and runs the demo agent against it. The manifests are awp-sim's (`awp-sim manifest --mode lockstep`, `--mode streaming`). [`frames.json`](frames.json) gives the harness one sample payload per channel.
15
+
16
+ ```bash
17
+ pip install --pre awp-python awp-conformance
18
+ awp-conformance agent --manifest conformance/manifest-lockstep.json --frames conformance/frames.json \
19
+ --mode lockstep --out report/ -- awp-demo --url '{url}' --token '{token}'
20
+ ```
21
+
22
+ For streaming, use `manifest-streaming.json` with `--mode streaming`. CI runs both on every change. The tests cited below run in CI too:
23
+
24
+ ```bash
25
+ uv run pytest tests/test_frames.py tests/test_evidence.py
26
+ ```
27
+
28
+ ## Manual evidence
29
+
30
+ ### AWP-DAT-001, AWP-DAT-009: loss accounting at the receiver (lockstep)
31
+
32
+ In streaming, the suite reads the agent's loss accounting from its `obs.report`. Lockstep sessions send no `obs.report`, so these rows are `manual` there.
33
+
34
+ - `test_the_receiver_counts_seq_gaps_as_loss_but_not_the_gap_before_a_resync` (`tests/test_evidence.py`) runs in each time model:
35
+ - on one channel, frames that skip two `seq` values count two missing frames in `ClientConnection.delivery()`;
36
+ - on another, a resync frame after a gap of five counts none.
37
+ - The client holds no delta state. Each frame reaches the application whole, with its `keyframe` and `resync` flags.
38
+
39
+ ### AWP-DAT-008: frame test vectors
40
+
41
+ `test_vectors` (`tests/test_frames.py`) runs `awp.frames` over every vector in `schemas/test-vectors/frames.json` of the `spec/` submodule, which is pinned at `spec-v0.1-draft.9`:
42
+
43
+ - the 10 valid vectors decode to their listed fields;
44
+ - the 7 marked `expect_error` are rejected with their listed error.
45
+
46
+ `test_roundtrip_without_vendor` re-encodes the 8 valid vectors that have no unknown extension or reserved bits, and each matches byte for byte.
47
+
48
+ ### AWP-VER-009: the draft revision is named
49
+
50
+ - The [README](../README.md) and the [Python SDK page](https://www.agentworldprotocol.com/sdks/python) name `0.1-draft.9`.
51
+ - `awp.SPEC_REVISION` is `"0.1-draft.9"`.
52
+ - The `spec/` submodule is pinned at the tag `spec-v0.1-draft.9`.
53
+ - Each report records `"specification": "0.1-draft.9"`, and its claim names the revision.