awp-python 0.1.0a5__tar.gz → 0.1.0a7__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 (80) hide show
  1. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/CHANGELOG.md +12 -0
  2. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/PKG-INFO +5 -5
  3. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/README.md +4 -4
  4. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/conformance/README.md +9 -9
  5. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/conformance/core-agent-lockstep.json +57 -9
  6. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/conformance/core-agent-streaming.json +63 -15
  7. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/pyproject.toml +1 -1
  8. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/__init__.py +1 -1
  9. awp_python-0.1.0a7/src/awp/_spec/schemas/profiles/input-chunk.schema.json +76 -0
  10. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/client.py +3 -0
  11. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/test_client.py +13 -0
  12. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/uv.lock +1 -1
  13. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/.gitignore +0 -0
  14. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/.gitmodules +0 -0
  15. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/.python-version +0 -0
  16. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/AGENTS.md +0 -0
  17. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/CLAUDE.md +0 -0
  18. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/LICENSE +0 -0
  19. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/conformance/frames.json +0 -0
  20. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/conformance/manifest-lockstep.json +0 -0
  21. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/conformance/manifest-streaming.json +0 -0
  22. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/scripts/sync_spec.py +0 -0
  23. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/lifecycle.json +0 -0
  24. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/action-cancel-result.schema.json +0 -0
  25. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/action-ref.schema.json +0 -0
  26. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/action-schema.schema.json +0 -0
  27. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/action-status.schema.json +0 -0
  28. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/action-submit-result.schema.json +0 -0
  29. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/action-submit.schema.json +0 -0
  30. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/agent-manifest.schema.json +0 -0
  31. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/approval-requested.schema.json +0 -0
  32. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/approval-respond.schema.json +0 -0
  33. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/common.schema.json +0 -0
  34. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/embodiment.schema.json +0 -0
  35. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/empty-result.schema.json +0 -0
  36. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/error.schema.json +0 -0
  37. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/frame-inline.schema.json +0 -0
  38. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/frame-tree.schema.json +0 -0
  39. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/obs-report.schema.json +0 -0
  40. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/observation-channel.schema.json +0 -0
  41. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/ping-result.schema.json +0 -0
  42. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/ping.schema.json +0 -0
  43. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/profiles/gui-actions.schema.json +0 -0
  44. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/reset-result.schema.json +0 -0
  45. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/reset.schema.json +0 -0
  46. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/restore.schema.json +0 -0
  47. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/safety-policy.schema.json +0 -0
  48. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-open.schema.json +0 -0
  49. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-ready.schema.json +0 -0
  50. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-resume.schema.json +0 -0
  51. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-state.schema.json +0 -0
  52. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-telemetry.schema.json +0 -0
  53. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-transfer-result.schema.json +0 -0
  54. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/session-transfer.schema.json +0 -0
  55. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/snapshot-result.schema.json +0 -0
  56. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/subscribe-result.schema.json +0 -0
  57. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/subscribe.schema.json +0 -0
  58. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/task-update.schema.json +0 -0
  59. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/tick-result.schema.json +0 -0
  60. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/tick.schema.json +0 -0
  61. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/unsubscribe.schema.json +0 -0
  62. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/world-event.schema.json +0 -0
  63. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/_spec/schemas/world-manifest.schema.json +0 -0
  64. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/aio.py +0 -0
  65. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/clock.py +0 -0
  66. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/demo.py +0 -0
  67. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/errors.py +0 -0
  68. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/frames.py +0 -0
  69. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/jsonrpc.py +0 -0
  70. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/lifecycle.py +0 -0
  71. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/py.typed +0 -0
  72. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/src/awp/schema.py +0 -0
  73. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/__init__.py +0 -0
  74. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/conftest.py +0 -0
  75. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/test_aio.py +0 -0
  76. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/test_client_traces.py +0 -0
  77. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/test_evidence.py +0 -0
  78. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/test_frames.py +0 -0
  79. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/test_schema.py +0 -0
  80. {awp_python-0.1.0a5 → awp_python-0.1.0a7}/tests/world.py +0 -0
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0a7
4
+
5
+ Targets specification revision `0.1-draft.11`.
6
+
7
+ - The bundled schemas add the game profile's `input_chunk` params schema, `profiles/input-chunk.schema.json`. The client is otherwise unchanged.
8
+
9
+ ## 0.1.0a6
10
+
11
+ Targets specification revision `0.1-draft.10`.
12
+
13
+ - When one of a multi-bind session's embodiments is transferred away, the client stops counting it as bound (AWP-EMB-003).
14
+
3
15
  ## 0.1.0a5
4
16
 
5
17
  Targets specification revision `0.1-draft.9`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: awp-python
3
- Version: 0.1.0a5
3
+ Version: 0.1.0a7
4
4
  Summary: Agent World Protocol agent SDK for Python.
5
5
  Project-URL: Specification, https://www.agentworldprotocol.com
6
6
  Project-URL: Source, https://github.com/Hyperduality/awp-python
@@ -23,13 +23,13 @@ Description-Content-Type: text/markdown
23
23
 
24
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
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.
26
+ It targets specification revision **`0.1-draft.11`**, 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
27
 
28
28
  ## Status
29
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)
30
+ ![AWP: Core Agent, AWP-conformant against 0.1-draft.11](https://img.shields.io/badge/AWP-Core_Agent%2C_conformant_0.1--draft.11-555)
31
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.
32
+ In both time models, the demo agent built on the client is **Core Agent: AWP-conformant against 0.1-draft.11**. [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.
33
33
 
34
34
  Implemented:
35
35
 
@@ -108,7 +108,7 @@ src/awp/ client protocol layer (sans-IO), asyncio adapter, frame code
108
108
  src/awp/_spec/ schemas and lifecycle table bundled from spec/ (scripts/sync_spec.py)
109
109
  tests/ unit tests, and a scripted world that serves over WebSockets
110
110
  conformance/ conformance reports, the manifests they were run against, and evidence
111
- spec/ agent-world-protocol, pinned at spec-v0.1-draft.9
111
+ spec/ agent-world-protocol, pinned at spec-v0.1-draft.11
112
112
  ```
113
113
 
114
114
  ## Development
@@ -2,13 +2,13 @@
2
2
 
3
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
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.
5
+ It targets specification revision **`0.1-draft.11`**, 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
6
 
7
7
  ## Status
8
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)
9
+ ![AWP: Core Agent, AWP-conformant against 0.1-draft.11](https://img.shields.io/badge/AWP-Core_Agent%2C_conformant_0.1--draft.11-555)
10
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.
11
+ In both time models, the demo agent built on the client is **Core Agent: AWP-conformant against 0.1-draft.11**. [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.
12
12
 
13
13
  Implemented:
14
14
 
@@ -87,7 +87,7 @@ src/awp/ client protocol layer (sans-IO), asyncio adapter, frame code
87
87
  src/awp/_spec/ schemas and lifecycle table bundled from spec/ (scripts/sync_spec.py)
88
88
  tests/ unit tests, and a scripted world that serves over WebSockets
89
89
  conformance/ conformance reports, the manifests they were run against, and evidence
90
- spec/ agent-world-protocol, pinned at spec-v0.1-draft.9
90
+ spec/ agent-world-protocol, pinned at spec-v0.1-draft.11
91
91
  ```
92
92
 
93
93
  ## Development
@@ -1,13 +1,13 @@
1
1
  # Conformance
2
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)
3
+ ![AWP: Core Agent, AWP-conformant against 0.1-draft.11](https://img.shields.io/badge/AWP-Core_Agent%2C_conformant_0.1--draft.11-555)
4
4
 
5
5
  | Class | Configuration | Claim | Report |
6
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.0a6) | [`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.0a6) | [`core-agent-streaming.json`](core-agent-streaming.json) |
7
+ | Core Agent | `awp-demo`, [`manifest-lockstep.json`](manifest-lockstep.json) | Core Agent (lockstep): AWP-conformant against 0.1-draft.11 (awp-conformance 0.1.0a9) | [`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.11 (awp-conformance 0.1.0a9) | [`core-agent-streaming.json`](core-agent-streaming.json) |
9
9
 
10
- The reports come from awp-conformance 0.1.0a6 run against awp-python 0.1.0a5. Neither has a failure or anything untested. The evidence for their `manual` rows is below (AWP-CNF-005).
10
+ The reports come from awp-conformance 0.1.0a9 run against awp-python 0.1.0a7. Neither has a failure or anything untested. The evidence for their `manual` rows is below (AWP-CNF-005).
11
11
 
12
12
  ## Reproduce
13
13
 
@@ -38,7 +38,7 @@ In streaming, the suite reads the agent's loss accounting from its `obs.report`.
38
38
 
39
39
  ### AWP-DAT-008: frame test vectors
40
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`:
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.11`:
42
42
 
43
43
  - the 10 valid vectors decode to their listed fields;
44
44
  - the 10 marked `expect_error` are rejected with their listed error.
@@ -47,7 +47,7 @@ In streaming, the suite reads the agent's loss accounting from its `obs.report`.
47
47
 
48
48
  ### AWP-VER-009: the draft revision is named
49
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.
50
+ - The [README](../README.md) and the [Python SDK page](https://www.agentworldprotocol.com/sdks/python) name `0.1-draft.11`.
51
+ - `awp.SPEC_REVISION` is `"0.1-draft.11"`.
52
+ - The `spec/` submodule is pinned at the tag `spec-v0.1-draft.11`.
53
+ - Each report records `"specification": "0.1-draft.11"`, and its claim names the revision.
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "suite": {
3
3
  "name": "awp-conformance",
4
- "version": "0.1.0a6"
4
+ "version": "0.1.0a9"
5
5
  },
6
- "specification": "0.1-draft.9",
6
+ "specification": "0.1-draft.11",
7
7
  "target": "awp-demo --url {url} --token {token}",
8
8
  "side": "agent",
9
- "generated": "2026-09-26T18:45:07Z",
9
+ "generated": "2026-10-18T20:42:31Z",
10
10
  "claim": {
11
11
  "status": "conformant",
12
- "wording": "Core Agent (lockstep): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a6)",
12
+ "wording": "Core Agent (lockstep): AWP-conformant against 0.1-draft.11 (awp-conformance 0.1.0a9)",
13
13
  "classes": [
14
14
  "Core Agent"
15
15
  ],
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "counts": {
28
28
  "manual": 4,
29
- "n/a": 193,
29
+ "n/a": 201,
30
30
  "pass": 37,
31
31
  "untestable": 3
32
32
  }
@@ -138,7 +138,7 @@
138
138
  "id": "AWP-AGT-006",
139
139
  "level": "MUST",
140
140
  "outcome": "pass",
141
- "detail": "24 check(s): lockstep/baseline, lockstep/integer-range, lockstep/malformed-frame, lockstep/reconnect, lockstep/restarted-world, lockstep/silent-world"
141
+ "detail": "22 check(s): lockstep/baseline, lockstep/malformed-frame, lockstep/reconnect, lockstep/restarted-world, lockstep/silent-world"
142
142
  },
143
143
  {
144
144
  "id": "AWP-AGT-007",
@@ -288,7 +288,7 @@
288
288
  "id": "AWP-CLK-006",
289
289
  "level": "MUST",
290
290
  "outcome": "pass",
291
- "detail": "41 check(s): lockstep/baseline, lockstep/integer-range, lockstep/malformed-frame, lockstep/no-action-grants, lockstep/reconnect, lockstep/refused-submission, lockstep/restarted-world, lockstep/silent-world"
291
+ "detail": "43 check(s): lockstep/baseline, lockstep/integer-range, lockstep/malformed-frame, lockstep/no-action-grants, lockstep/reconnect, lockstep/refused-submission, lockstep/restarted-world, lockstep/silent-world"
292
292
  },
293
293
  {
294
294
  "id": "AWP-CLK-007",
@@ -356,6 +356,12 @@
356
356
  "outcome": "n/a",
357
357
  "detail": "world-side requirement"
358
358
  },
359
+ {
360
+ "id": "AWP-CMD-009",
361
+ "level": "SHOULD",
362
+ "outcome": "n/a",
363
+ "detail": "world-side requirement"
364
+ },
359
365
  {
360
366
  "id": "AWP-CNF-001",
361
367
  "level": "MUST",
@@ -414,7 +420,7 @@
414
420
  "id": "AWP-CTL-004",
415
421
  "level": "MUST",
416
422
  "outcome": "pass",
417
- "detail": "41 check(s): lockstep/baseline, lockstep/integer-range, lockstep/malformed-frame, lockstep/no-action-grants, lockstep/reconnect, lockstep/refused-submission, lockstep/restarted-world, lockstep/silent-world"
423
+ "detail": "43 check(s): lockstep/baseline, lockstep/integer-range, lockstep/malformed-frame, lockstep/no-action-grants, lockstep/reconnect, lockstep/refused-submission, lockstep/restarted-world, lockstep/silent-world"
418
424
  },
419
425
  {
420
426
  "id": "AWP-CTL-005",
@@ -596,6 +602,36 @@
596
602
  "outcome": "n/a",
597
603
  "detail": "world-side requirement"
598
604
  },
605
+ {
606
+ "id": "AWP-EVT-004",
607
+ "level": "MUST",
608
+ "outcome": "n/a",
609
+ "detail": "world-side requirement"
610
+ },
611
+ {
612
+ "id": "AWP-GAM-001",
613
+ "level": "MUST",
614
+ "outcome": "n/a",
615
+ "detail": "world-side requirement"
616
+ },
617
+ {
618
+ "id": "AWP-GAM-002",
619
+ "level": "MUST",
620
+ "outcome": "n/a",
621
+ "detail": "world-side requirement"
622
+ },
623
+ {
624
+ "id": "AWP-GAM-003",
625
+ "level": "MUST",
626
+ "outcome": "n/a",
627
+ "detail": "world-side requirement"
628
+ },
629
+ {
630
+ "id": "AWP-GAM-004",
631
+ "level": "MUST",
632
+ "outcome": "n/a",
633
+ "detail": "world-side requirement"
634
+ },
599
635
  {
600
636
  "id": "AWP-GUI-001",
601
637
  "level": "MUST",
@@ -980,6 +1016,12 @@
980
1016
  "outcome": "n/a",
981
1017
  "detail": "world-side requirement"
982
1018
  },
1019
+ {
1020
+ "id": "AWP-ROB-008",
1021
+ "level": "SHOULD",
1022
+ "outcome": "n/a",
1023
+ "detail": "world-side requirement"
1024
+ },
983
1025
  {
984
1026
  "id": "AWP-SAF-001",
985
1027
  "level": "MUST",
@@ -1206,7 +1248,7 @@
1206
1248
  "id": "AWP-TIM-003",
1207
1249
  "level": "MUST",
1208
1250
  "outcome": "pass",
1209
- "detail": "6 check(s): lockstep/baseline, lockstep/reconnect, lockstep/restarted-world"
1251
+ "detail": "8 check(s): lockstep/baseline, lockstep/malformed-frame, lockstep/reconnect, lockstep/restarted-world"
1210
1252
  },
1211
1253
  {
1212
1254
  "id": "AWP-TIM-004",
@@ -1268,6 +1310,12 @@
1268
1310
  "outcome": "n/a",
1269
1311
  "detail": "world-side requirement"
1270
1312
  },
1313
+ {
1314
+ "id": "AWP-TIM-014",
1315
+ "level": "MUST",
1316
+ "outcome": "n/a",
1317
+ "detail": "world-side requirement"
1318
+ },
1271
1319
  {
1272
1320
  "id": "AWP-TRN-001",
1273
1321
  "level": "MUST",
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "suite": {
3
3
  "name": "awp-conformance",
4
- "version": "0.1.0a6"
4
+ "version": "0.1.0a9"
5
5
  },
6
- "specification": "0.1-draft.9",
6
+ "specification": "0.1-draft.11",
7
7
  "target": "awp-demo --url {url} --token {token}",
8
8
  "side": "agent",
9
- "generated": "2026-09-26T18:45:09Z",
9
+ "generated": "2026-10-18T20:42:54Z",
10
10
  "claim": {
11
11
  "status": "conformant",
12
- "wording": "Core Agent (streaming): AWP-conformant against 0.1-draft.9 (awp-conformance 0.1.0a6)",
12
+ "wording": "Core Agent (streaming): AWP-conformant against 0.1-draft.11 (awp-conformance 0.1.0a9)",
13
13
  "classes": [
14
14
  "Core Agent"
15
15
  ],
@@ -24,7 +24,7 @@
24
24
  ],
25
25
  "counts": {
26
26
  "manual": 2,
27
- "n/a": 187,
27
+ "n/a": 195,
28
28
  "pass": 45,
29
29
  "untestable": 3
30
30
  }
@@ -106,7 +106,7 @@
106
106
  "id": "AWP-AGT-001",
107
107
  "level": "MUST",
108
108
  "outcome": "pass",
109
- "detail": "146 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
109
+ "detail": "147 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
110
110
  },
111
111
  {
112
112
  "id": "AWP-AGT-002",
@@ -136,7 +136,7 @@
136
136
  "id": "AWP-AGT-006",
137
137
  "level": "MUST",
138
138
  "outcome": "pass",
139
- "detail": "17 check(s): streaming/baseline, streaming/frame-gaps, streaming/malformed-frame, streaming/reconnect, streaming/restarted-world"
139
+ "detail": "18 check(s): streaming/baseline, streaming/frame-gaps, streaming/malformed-frame, streaming/reconnect, streaming/restarted-world"
140
140
  },
141
141
  {
142
142
  "id": "AWP-AGT-007",
@@ -286,13 +286,13 @@
286
286
  "id": "AWP-CLK-006",
287
287
  "level": "MUST",
288
288
  "outcome": "pass",
289
- "detail": "55 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
289
+ "detail": "56 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
290
290
  },
291
291
  {
292
292
  "id": "AWP-CLK-007",
293
293
  "level": "MUST",
294
294
  "outcome": "pass",
295
- "detail": "16 check(s): streaming/baseline, streaming/frame-gaps, streaming/malformed-frame, streaming/reconnect, streaming/restarted-world"
295
+ "detail": "17 check(s): streaming/baseline, streaming/frame-gaps, streaming/malformed-frame, streaming/reconnect, streaming/restarted-world"
296
296
  },
297
297
  {
298
298
  "id": "AWP-CLK-008",
@@ -354,6 +354,12 @@
354
354
  "outcome": "n/a",
355
355
  "detail": "world-side requirement"
356
356
  },
357
+ {
358
+ "id": "AWP-CMD-009",
359
+ "level": "SHOULD",
360
+ "outcome": "n/a",
361
+ "detail": "world-side requirement"
362
+ },
357
363
  {
358
364
  "id": "AWP-CNF-001",
359
365
  "level": "MUST",
@@ -394,7 +400,7 @@
394
400
  "id": "AWP-CTL-001",
395
401
  "level": "MUST",
396
402
  "outcome": "pass",
397
- "detail": "158 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
403
+ "detail": "160 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
398
404
  },
399
405
  {
400
406
  "id": "AWP-CTL-002",
@@ -412,7 +418,7 @@
412
418
  "id": "AWP-CTL-004",
413
419
  "level": "MUST",
414
420
  "outcome": "pass",
415
- "detail": "55 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
421
+ "detail": "56 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
416
422
  },
417
423
  {
418
424
  "id": "AWP-CTL-005",
@@ -424,7 +430,7 @@
424
430
  "id": "AWP-CTL-006",
425
431
  "level": "MUST",
426
432
  "outcome": "pass",
427
- "detail": "158 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
433
+ "detail": "160 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
428
434
  },
429
435
  {
430
436
  "id": "AWP-CTL-007",
@@ -442,7 +448,7 @@
442
448
  "id": "AWP-CTL-009",
443
449
  "level": "MUST",
444
450
  "outcome": "pass",
445
- "detail": "160 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
451
+ "detail": "162 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
446
452
  },
447
453
  {
448
454
  "id": "AWP-CTL-010",
@@ -594,6 +600,36 @@
594
600
  "outcome": "n/a",
595
601
  "detail": "world-side requirement"
596
602
  },
603
+ {
604
+ "id": "AWP-EVT-004",
605
+ "level": "MUST",
606
+ "outcome": "n/a",
607
+ "detail": "world-side requirement"
608
+ },
609
+ {
610
+ "id": "AWP-GAM-001",
611
+ "level": "MUST",
612
+ "outcome": "n/a",
613
+ "detail": "world-side requirement"
614
+ },
615
+ {
616
+ "id": "AWP-GAM-002",
617
+ "level": "MUST",
618
+ "outcome": "n/a",
619
+ "detail": "world-side requirement"
620
+ },
621
+ {
622
+ "id": "AWP-GAM-003",
623
+ "level": "MUST",
624
+ "outcome": "n/a",
625
+ "detail": "world-side requirement"
626
+ },
627
+ {
628
+ "id": "AWP-GAM-004",
629
+ "level": "MUST",
630
+ "outcome": "n/a",
631
+ "detail": "world-side requirement"
632
+ },
597
633
  {
598
634
  "id": "AWP-GUI-001",
599
635
  "level": "MUST",
@@ -978,11 +1014,17 @@
978
1014
  "outcome": "n/a",
979
1015
  "detail": "world-side requirement"
980
1016
  },
1017
+ {
1018
+ "id": "AWP-ROB-008",
1019
+ "level": "SHOULD",
1020
+ "outcome": "n/a",
1021
+ "detail": "world-side requirement"
1022
+ },
981
1023
  {
982
1024
  "id": "AWP-SAF-001",
983
1025
  "level": "MUST",
984
1026
  "outcome": "pass",
985
- "detail": "17 check(s): streaming/baseline, streaming/frame-gaps, streaming/malformed-frame, streaming/reconnect, streaming/restarted-world"
1027
+ "detail": "18 check(s): streaming/baseline, streaming/frame-gaps, streaming/malformed-frame, streaming/reconnect, streaming/restarted-world"
986
1028
  },
987
1029
  {
988
1030
  "id": "AWP-SAF-002",
@@ -1266,6 +1308,12 @@
1266
1308
  "outcome": "n/a",
1267
1309
  "detail": "world-side requirement"
1268
1310
  },
1311
+ {
1312
+ "id": "AWP-TIM-014",
1313
+ "level": "MUST",
1314
+ "outcome": "n/a",
1315
+ "detail": "world-side requirement"
1316
+ },
1269
1317
  {
1270
1318
  "id": "AWP-TRN-001",
1271
1319
  "level": "MUST",
@@ -1420,7 +1468,7 @@
1420
1468
  "id": "AWP-VER-004",
1421
1469
  "level": "MUST",
1422
1470
  "outcome": "pass",
1423
- "detail": "132 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
1471
+ "detail": "133 check(s): streaming/baseline, streaming/frame-gaps, streaming/integer-range, streaming/invalid-manifest, streaming/malformed-frame, streaming/no-action-grants, streaming/reconnect, streaming/refused-submission, streaming/restarted-world, streaming/silent-world"
1424
1472
  },
1425
1473
  {
1426
1474
  "id": "AWP-VER-005",
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "awp-python"
7
- version = "0.1.0a5"
7
+ version = "0.1.0a7"
8
8
  description = "Agent World Protocol agent SDK for Python."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -28,7 +28,7 @@ from .errors import AwpError, ErrorCode, ProtocolError
28
28
  from .frames import Frame
29
29
  from .lifecycle import ActionState
30
30
 
31
- SPEC_REVISION = "0.1-draft.9"
31
+ SPEC_REVISION = "0.1-draft.11"
32
32
  PROTOCOL_VERSION = "0.1"
33
33
 
34
34
  try:
@@ -0,0 +1,76 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentworldprotocol.com/schemas/v0.1/profiles/input-chunk.schema.json",
4
+ "title": "Game profile input_chunk params (AWP-GAM-001)",
5
+ "description": "Normative params_schema for the reserved action type input_chunk: device state for keyboard, mouse, and gamepad in fixed-length slots. +x is right and +y is down. Mouse and scroll deltas are device counts, a documented exception to AWP-UNI-001.",
6
+ "type": "object",
7
+ "properties": {
8
+ "slot_ms": { "type": "integer", "minimum": 1, "maximum": 1000, "description": "Length of every slot, in milliseconds." },
9
+ "slots": {
10
+ "type": "array", "minItems": 1, "maxItems": 256,
11
+ "description": "Device states in execution order; each holds for slot_ms.",
12
+ "items": {
13
+ "type": "object",
14
+ "properties": {
15
+ "keys": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/key_name" }, "description": "Keys and buttons held down for the slot; any key not listed is up." },
16
+ "mouse_dx": { "type": "integer", "minimum": -32768, "maximum": 32767, "description": "Horizontal mouse motion over the slot, in device counts; positive is right." },
17
+ "mouse_dy": { "type": "integer", "minimum": -32768, "maximum": 32767, "description": "Vertical mouse motion over the slot, in device counts; positive is down." },
18
+ "scroll_steps": { "type": "integer", "minimum": -127, "maximum": 127, "description": "Wheel detents over the slot; positive moves the wheel away from the user." },
19
+ "sticks": {
20
+ "type": "object",
21
+ "description": "Analog stick deflection held for the slot; an absent axis is centered.",
22
+ "properties": {
23
+ "left_x": { "type": "number", "minimum": -1, "maximum": 1, "description": "Left stick, horizontal, unitless; positive is right." },
24
+ "left_y": { "type": "number", "minimum": -1, "maximum": 1, "description": "Left stick, vertical, unitless; positive is down." },
25
+ "right_x": { "type": "number", "minimum": -1, "maximum": 1, "description": "Right stick, horizontal, unitless; positive is right." },
26
+ "right_y": { "type": "number", "minimum": -1, "maximum": 1, "description": "Right stick, vertical, unitless; positive is down." }
27
+ },
28
+ "x-awp-closed": true
29
+ },
30
+ "triggers": {
31
+ "type": "object",
32
+ "description": "Analog trigger pull held for the slot (standard-mapping buttons 6 and 7); an absent trigger is released.",
33
+ "properties": {
34
+ "left": { "type": "number", "minimum": 0, "maximum": 1, "description": "Left trigger, unitless; 0 is released, 1 fully pulled." },
35
+ "right": { "type": "number", "minimum": 0, "maximum": 1, "description": "Right trigger, unitless; 0 is released, 1 fully pulled." }
36
+ },
37
+ "x-awp-closed": true
38
+ }
39
+ },
40
+ "x-awp-closed": true
41
+ }
42
+ }
43
+ },
44
+ "required": ["slot_ms", "slots"],
45
+ "x-awp-closed": true,
46
+ "$defs": {
47
+ "key_name": {
48
+ "description": "A W3C UI Events KeyboardEvent.code value other than Unidentified, a mouse button, or a button of the W3C Gamepad standard mapping named by position.",
49
+ "enum": [
50
+ "Backquote", "Backslash", "BracketLeft", "BracketRight", "Comma", "Digit0", "Digit1", "Digit2", "Digit3",
51
+ "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "Equal", "IntlBackslash", "IntlRo", "IntlYen",
52
+ "KeyA", "KeyB", "KeyC", "KeyD", "KeyE", "KeyF", "KeyG", "KeyH", "KeyI", "KeyJ", "KeyK", "KeyL", "KeyM",
53
+ "KeyN", "KeyO", "KeyP", "KeyQ", "KeyR", "KeyS", "KeyT", "KeyU", "KeyV", "KeyW", "KeyX", "KeyY", "KeyZ",
54
+ "Minus", "Period", "Quote", "Semicolon", "Slash", "AltLeft", "AltRight", "Backspace", "CapsLock",
55
+ "ContextMenu", "ControlLeft", "ControlRight", "Enter", "MetaLeft", "MetaRight", "ShiftLeft", "ShiftRight",
56
+ "Space", "Tab", "Convert", "KanaMode", "Lang1", "Lang2", "Lang3", "Lang4", "Lang5", "NonConvert", "Delete",
57
+ "End", "Help", "Home", "Insert", "PageDown", "PageUp", "ArrowDown", "ArrowLeft", "ArrowRight", "ArrowUp",
58
+ "NumLock", "Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8",
59
+ "Numpad9", "NumpadAdd", "NumpadBackspace", "NumpadClear", "NumpadClearEntry", "NumpadComma", "NumpadDecimal",
60
+ "NumpadDivide", "NumpadEnter", "NumpadEqual", "NumpadHash", "NumpadMemoryAdd", "NumpadMemoryClear",
61
+ "NumpadMemoryRecall", "NumpadMemoryStore", "NumpadMemorySubtract", "NumpadMultiply", "NumpadParenLeft",
62
+ "NumpadParenRight", "NumpadStar", "NumpadSubtract", "Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
63
+ "F9", "F10", "F11", "F12", "Fn", "FnLock", "PrintScreen", "ScrollLock", "Pause", "BrowserBack",
64
+ "BrowserFavorites", "BrowserForward", "BrowserHome", "BrowserRefresh", "BrowserSearch", "BrowserStop",
65
+ "Eject", "LaunchApp1", "LaunchApp2", "LaunchMail", "MediaPlayPause", "MediaSelect", "MediaStop",
66
+ "MediaTrackNext", "MediaTrackPrevious", "Power", "Sleep", "AudioVolumeDown", "AudioVolumeMute",
67
+ "AudioVolumeUp", "WakeUp", "Hyper", "Super", "Turbo", "Abort", "Resume", "Suspend", "Again", "Copy", "Cut",
68
+ "Find", "Open", "Paste", "Props", "Select", "Undo", "Hiragana", "Katakana", "MouseLeft", "MouseRight",
69
+ "MouseMiddle", "MouseBack", "MouseForward", "GamepadSouth", "GamepadEast", "GamepadWest", "GamepadNorth",
70
+ "GamepadLeftBumper", "GamepadRightBumper", "GamepadSelect", "GamepadStart", "GamepadLeftStick",
71
+ "GamepadRightStick", "GamepadDpadUp", "GamepadDpadDown", "GamepadDpadLeft", "GamepadDpadRight",
72
+ "GamepadHome"
73
+ ]
74
+ }
75
+ }
76
+ }
@@ -772,6 +772,9 @@ class ClientConnection:
772
772
  self._apply_status(params, events)
773
773
  elif method == "world.event":
774
774
  if self._sequence(params["status_seq"], events):
775
+ if params["event"] == "embodiment_transferred":
776
+ moved = (params.get("detail") or {}).get("embodiment")
777
+ self.embodiments = [e for e in self.embodiments if e != moved] # AWP-EMB-003
775
778
  events.append(WorldEvent(params["event"], params, self._replaying(params)))
776
779
  elif method == "session.state" and self._sequence(params["status_seq"], events):
777
780
  self.session_state = params["state"]
@@ -85,3 +85,16 @@ def test_the_clock_maps_both_ways_through_the_best_sample():
85
85
  clock.add(sample(100, 1_050, 1_050, 150)) # rtt 50: the one to trust
86
86
  assert (clock.offset_ns, clock.error_bound_ns) == (925, 25)
87
87
  assert clock.to_agent(clock.to_session(7_000)) == 7_000
88
+
89
+
90
+ def test_a_transferred_embodiment_is_no_longer_bound():
91
+ conn = ClientConnection(AGENT, MODALITIES, clock_ns=lambda: 0)
92
+ conn.receive(jsonrpc.result(conn.initialize(), manifest("streaming")))
93
+ rid = conn.open_session("streaming", embodiments=["arm_01", "gripper_01"])
94
+ conn.receive(jsonrpc.result(rid, ready("streaming", conn.outgoing()[-1]["params"])))
95
+ seq = conn.last_status_seq + 1
96
+ event = {"event": "embodiment_transferred", "status_seq": seq, "ts_mono_ns": 1}
97
+ event["detail"] = {"embodiment": "arm_01"}
98
+ conn.receive(jsonrpc.notification("world.event", event))
99
+ assert conn.embodiments == ["gripper_01"] # AWP-EMB-003
100
+ conn.submit("stop", {}) # one embodiment left: embodiment_id may be left out
@@ -81,7 +81,7 @@ wheels = [
81
81
 
82
82
  [[package]]
83
83
  name = "awp-python"
84
- version = "0.1.0a5"
84
+ version = "0.1.0a7"
85
85
  source = { editable = "." }
86
86
  dependencies = [
87
87
  { name = "jsonschema" },
File without changes
File without changes
File without changes
File without changes
File without changes