agentplane-primitives 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. agentplane_primitives-0.1.0/.gitignore +32 -0
  2. agentplane_primitives-0.1.0/CHANGELOG.md +40 -0
  3. agentplane_primitives-0.1.0/LICENSE +21 -0
  4. agentplane_primitives-0.1.0/PKG-INFO +211 -0
  5. agentplane_primitives-0.1.0/README.md +185 -0
  6. agentplane_primitives-0.1.0/docs/adr/0001-record-architecture-decisions.md +55 -0
  7. agentplane_primitives-0.1.0/docs/adr/0002-closed-kind-enum.md +60 -0
  8. agentplane_primitives-0.1.0/docs/adr/0003-api-models-live-in-control-plane.md +68 -0
  9. agentplane_primitives-0.1.0/docs/adr/0004-envelope-sections.md +68 -0
  10. agentplane_primitives-0.1.0/docs/adr/0005-three-tiers-trace-span-envelope.md +65 -0
  11. agentplane_primitives-0.1.0/docs/adr/README.md +50 -0
  12. agentplane_primitives-0.1.0/docs/adr/template.md +58 -0
  13. agentplane_primitives-0.1.0/docs/design.md +20 -0
  14. agentplane_primitives-0.1.0/docs/versioning.md +36 -0
  15. agentplane_primitives-0.1.0/pyproject.toml +113 -0
  16. agentplane_primitives-0.1.0/src/agentplane_primitives/__init__.py +10 -0
  17. agentplane_primitives-0.1.0/src/agentplane_primitives/_version.py +3 -0
  18. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/__init__.py +25 -0
  19. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/base_enum.py +15 -0
  20. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/finish_reason.py +17 -0
  21. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/kind.py +14 -0
  22. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/link_type.py +12 -0
  23. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/message_role.py +12 -0
  24. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/model_source.py +17 -0
  25. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/state.py +13 -0
  26. agentplane_primitives-0.1.0/src/agentplane_primitives/enums/status.py +14 -0
  27. agentplane_primitives-0.1.0/src/agentplane_primitives/models/__init__.py +46 -0
  28. agentplane_primitives-0.1.0/src/agentplane_primitives/models/base.py +20 -0
  29. agentplane_primitives-0.1.0/src/agentplane_primitives/models/content_block.py +19 -0
  30. agentplane_primitives-0.1.0/src/agentplane_primitives/models/envelope.py +94 -0
  31. agentplane_primitives-0.1.0/src/agentplane_primitives/models/envelope_status.py +28 -0
  32. agentplane_primitives-0.1.0/src/agentplane_primitives/models/link.py +16 -0
  33. agentplane_primitives-0.1.0/src/agentplane_primitives/models/llm_input.py +33 -0
  34. agentplane_primitives-0.1.0/src/agentplane_primitives/models/llm_output.py +43 -0
  35. agentplane_primitives-0.1.0/src/agentplane_primitives/models/llm_params.py +19 -0
  36. agentplane_primitives-0.1.0/src/agentplane_primitives/models/message.py +26 -0
  37. agentplane_primitives-0.1.0/src/agentplane_primitives/models/output_error.py +18 -0
  38. agentplane_primitives-0.1.0/src/agentplane_primitives/models/reasoning_block.py +12 -0
  39. agentplane_primitives-0.1.0/src/agentplane_primitives/models/refusal_block.py +12 -0
  40. agentplane_primitives-0.1.0/src/agentplane_primitives/models/registry.py +15 -0
  41. agentplane_primitives-0.1.0/src/agentplane_primitives/models/span.py +48 -0
  42. agentplane_primitives-0.1.0/src/agentplane_primitives/models/text_block.py +12 -0
  43. agentplane_primitives-0.1.0/src/agentplane_primitives/models/tool_call_block.py +16 -0
  44. agentplane_primitives-0.1.0/src/agentplane_primitives/models/tool_input.py +15 -0
  45. agentplane_primitives-0.1.0/src/agentplane_primitives/models/tool_output.py +17 -0
  46. agentplane_primitives-0.1.0/src/agentplane_primitives/models/trace.py +29 -0
  47. agentplane_primitives-0.1.0/src/agentplane_primitives/models/trace_context.py +29 -0
  48. agentplane_primitives-0.1.0/src/agentplane_primitives/models/usage.py +21 -0
  49. agentplane_primitives-0.1.0/src/agentplane_primitives/py.typed +0 -0
  50. agentplane_primitives-0.1.0/src/agentplane_primitives/schemas/Envelope.json +808 -0
  51. agentplane_primitives-0.1.0/src/agentplane_primitives/schemas/README.md +39 -0
  52. agentplane_primitives-0.1.0/src/agentplane_primitives/schemas/Span.json +116 -0
  53. agentplane_primitives-0.1.0/src/agentplane_primitives/schemas/Trace.json +88 -0
  54. agentplane_primitives-0.1.0/src/agentplane_primitives/types/__init__.py +36 -0
  55. agentplane_primitives-0.1.0/src/agentplane_primitives/types/id_types.py +48 -0
  56. agentplane_primitives-0.1.0/src/agentplane_primitives/types/metadata_types.py +32 -0
  57. agentplane_primitives-0.1.0/src/agentplane_primitives/types/provider_types.py +18 -0
  58. agentplane_primitives-0.1.0/src/agentplane_primitives/types/schema_version_types.py +18 -0
  59. agentplane_primitives-0.1.0/src/agentplane_primitives/utils/__init__.py +25 -0
  60. agentplane_primitives-0.1.0/src/agentplane_primitives/utils/id_utils.py +32 -0
  61. agentplane_primitives-0.1.0/src/agentplane_primitives/utils/lifecycle_utils.py +33 -0
  62. agentplane_primitives-0.1.0/src/agentplane_primitives/utils/metadata_utils.py +11 -0
  63. agentplane_primitives-0.1.0/src/agentplane_primitives/utils/schema_utils.py +23 -0
  64. agentplane_primitives-0.1.0/src/agentplane_primitives/utils/traceparent_utils.py +63 -0
  65. agentplane_primitives-0.1.0/tests/test_base.py +17 -0
  66. agentplane_primitives-0.1.0/tests/test_enums.py +25 -0
  67. agentplane_primitives-0.1.0/tests/test_envelope.py +109 -0
  68. agentplane_primitives-0.1.0/tests/test_envelope_status.py +40 -0
  69. agentplane_primitives-0.1.0/tests/test_id_types.py +33 -0
  70. agentplane_primitives-0.1.0/tests/test_id_utils.py +34 -0
  71. agentplane_primitives-0.1.0/tests/test_llm.py +167 -0
  72. agentplane_primitives-0.1.0/tests/test_metadata_types.py +23 -0
  73. agentplane_primitives-0.1.0/tests/test_metadata_utils.py +9 -0
  74. agentplane_primitives-0.1.0/tests/test_package.py +15 -0
  75. agentplane_primitives-0.1.0/tests/test_pr_size.py +49 -0
  76. agentplane_primitives-0.1.0/tests/test_schemas.py +52 -0
  77. agentplane_primitives-0.1.0/tests/test_trace_and_span.py +97 -0
  78. agentplane_primitives-0.1.0/tests/test_traceparent_utils.py +76 -0
@@ -0,0 +1,32 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+
7
+ # Environments
8
+ .venv/
9
+ venv/
10
+ .env
11
+ .env.*
12
+ !.env.example
13
+
14
+ # Build and packaging
15
+ build/
16
+ dist/
17
+ *.whl
18
+
19
+ # Tooling caches
20
+ .pytest_cache/
21
+ .mypy_cache/
22
+ .ruff_cache/
23
+ .coverage
24
+ .coverage.*
25
+ htmlcov/
26
+ coverage.xml
27
+
28
+ # Editors and OS
29
+ .idea/
30
+ .vscode/
31
+ .DS_Store
32
+ Thumbs.db
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ All notable changes are recorded here, following [Keep a Changelog](https://keepachangelog.com/)
4
+ and [SemVer](https://semver.org/). Each entry is classified as **compatible** or **breaking** and
5
+ names the migration each consumer needs (see [docs/versioning.md](docs/versioning.md)).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-10-12
10
+
11
+ First release. Schema version `0.1`. Everything below is new, so every entry is **compatible**; there
12
+ is nothing to migrate from. Pre-1.0: pin the exact minor (`agentplane-primitives==0.1.*`).
13
+
14
+ ### Added
15
+ - **Entities:** `Trace` (labels are strings, no status of its own), `Span` (`parent_envelope_id`
16
+ links it to the caller) and `Envelope` with identity fields at the top level and nested
17
+ `envelope_status`, `input`, `output` and `metadata`; `attempt` and `links` (`retry_of`).
18
+ - **Kinds:** a closed `Kind` enum (`llm`, `tool`). `tool` input and output carry `raw` and an
19
+ optional `error`; `llm` input and output carry the canonical fields, `raw`, content blocks
20
+ (`text`, `tool_call`, `reasoning`, `refusal`), `finish_reason` and the fixed cost fields
21
+ `provider`, `model`, `model_source` and `usage` (five exclusive, additive token buckets).
22
+ - **Enums:** `Kind`, `State`, `Status`, `LinkType`, `FinishReason`, `ModelSource`, `MessageRole`.
23
+ A new member of any of them is a schema change.
24
+ - **Ids:** `TraceId` (32 hex), `SpanId` and `EnvelopeId` (16 hex), lowercase, never all zero, with
25
+ random generators.
26
+ - **`traceparent` carrier:** `TraceContext`, `parse_traceparent()` (strict, never raises:
27
+ anything malformed gives `None`) and `format_traceparent()`. `to_event` and `from_event` are
28
+ reserved names, documented and not implemented.
29
+ - **Metadata rules:** lowercase dot-separated keys, the reserved `chronicle.` prefix, string-valued
30
+ trace labels, and the well-known label keys `session_id`, `message_id` and `user_id`.
31
+ - **Schemas:** one committed JSON Schema file per stored entity (`Trace.json`, `Span.json`,
32
+ `Envelope.json`), generated by `python scripts/generate_schemas.py`; a test fails when they
33
+ drift from the models.
34
+ - **Versioning:** `schema_version` `"0.1"` on every persisted payload; unknown fields are ignored
35
+ on read.
36
+ - **Repository:** `src` layout, typed package (`py.typed`), CI, release workflow, dependency
37
+ updates, contribution and security docs, and ADRs 0001 to 0005 in `docs/adr/`.
38
+
39
+ **Not in this package:** HTTP request and response wrappers. The control plane owns them and
40
+ reuses these entities as bodies ([ADR 0003](docs/adr/0003-api-models-live-in-control-plane.md)).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tisha Chawla and Susheem Koul
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,211 @@
1
+ Metadata-Version: 2.5
2
+ Name: agentplane-primitives
3
+ Version: 0.1.0
4
+ Summary: Shared, versioned domain primitives (Trace, Span, Envelope) for the AgentPlane products.
5
+ Project-URL: Homepage, https://github.com/theagentplane/primitives
6
+ Project-URL: Repository, https://github.com/theagentplane/primitives
7
+ Project-URL: Issues, https://github.com/theagentplane/primitives/issues
8
+ Project-URL: Changelog, https://github.com/theagentplane/primitives/blob/main/CHANGELOG.md
9
+ Author: Tisha Chawla, Susheem Koul
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: agents,llm,observability,pydantic,schema,tracing
13
+ Classifier: Development Status :: 2 - Pre-Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: pydantic<3,>=2.6
25
+ Description-Content-Type: text/markdown
26
+
27
+ <div align="center">
28
+
29
+ # AgentPlane Primitives
30
+
31
+ **One schema for every agent trace.**<br>
32
+ <sub>Shared, versioned Trace, Span and Envelope models for Chronicle, the control plane and TokenOps.</sub>
33
+
34
+ [![CI](https://github.com/theagentplane/primitives/actions/workflows/ci.yml/badge.svg)](https://github.com/theagentplane/primitives/actions/workflows/ci.yml)
35
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://github.com/theagentplane/primitives)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
37
+ [![Typed](https://img.shields.io/badge/typing-strict-informational.svg)](https://peps.python.org/pep-0561/)
38
+ [![GitHub stars](https://img.shields.io/github/stars/theagentplane/primitives?style=social)](https://github.com/theagentplane/primitives/stargazers)
39
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-0A66C2?logo=linkedin&logoColor=white)](https://www.linkedin.com/company/the-agent-plane/)
40
+
41
+ <sub>Built by <b><a href="https://www.linkedin.com/in/susheemkoul/">Susheem Koul</a></b> and <b><a href="https://www.linkedin.com/in/tisha-chawla/">Tisha Chawla</a></b></sub>
42
+
43
+ <br>
44
+
45
+ [Core features](#-core-features) · [Quickstart](#-quickstart) · [How it fits](#-how-it-fits) · [Scope](#-scope) · [Versioning](#-versioning) · [Development](#-development) · [Support](#-support)
46
+
47
+ </div>
48
+
49
+ > ### 🚧 Pre-alpha
50
+ >
51
+ > This release is the repository scaffold. The models land in follow-up releases (see the
52
+ > [roadmap](#-roadmap)). Everything under *Core features* describes the
53
+ > [design](docs/design.md) these releases implement.
54
+
55
+ ## ✨ Core features
56
+
57
+ Chronicle records what an agent did, the control plane stores and shows it, and TokenOps reads
58
+ it to govern spend. Those three only work together if they agree on the shape of the data.
59
+ This package is that agreement, and nothing else.
60
+
61
+ | | |
62
+ |---|---|
63
+ | **Three tiers** | A `Trace` is one request across services, a `Span` is one service's handling of it, an `Envelope` is one boundary crossing inside the span. |
64
+ | **One definition, three repos** | Chronicle, the control plane and TokenOps import the same models. None defines its own copy. |
65
+ | **Closed enums** | `kind`, `state`, `status` and the other enumerations are closed sets. A new value is a deliberate schema change. |
66
+ | **Additive-only versioning** | SemVer for the package plus a `schema_version` on every payload. Nothing breaks within a major version. |
67
+ | **W3C `traceparent` carrier** | Parse and format the trace-context header so a trace follows a request across services. |
68
+ | **No I/O, one dependency** | Data and validation only, on pydantic. No network, no disk, no business logic. |
69
+ | **Contract you can read** | Generated JSON Schema, committed and checked in CI, for anything that is not Python. |
70
+
71
+ ## 🚀 Quickstart
72
+
73
+ Requires Python 3.10+. The package is typed ([PEP 561](https://peps.python.org/pep-0561/)).
74
+
75
+ ```bash
76
+ pip install agentplane-primitives # once the first release is published
77
+ ```
78
+
79
+ Until then, install from source:
80
+
81
+ ```bash
82
+ git clone https://github.com/theagentplane/primitives.git
83
+ cd primitives
84
+ pip install -e .
85
+ python -c "import agentplane_primitives as p; print(p.__version__)"
86
+ ```
87
+
88
+ ### When you need more
89
+
90
+ | You want to | Go to |
91
+ |---|---|
92
+ | Understand the entities and why there are three tiers | [Design](docs/design.md) |
93
+ | Know what may change between versions | [Versioning policy](docs/versioning.md) |
94
+ | Propose a new field or enum value | [Schema change proposal](https://github.com/theagentplane/primitives/issues/new?template=schema_change.yml) |
95
+ | Add a model | [Contributing](CONTRIBUTING.md) |
96
+ | Publish a release | [Releasing](RELEASING.md) |
97
+
98
+ ## 🧩 How it fits
99
+
100
+ ```mermaid
101
+ flowchart LR
102
+ P["primitives<br/>Trace · Span · Envelope"]
103
+ C["Chronicle<br/>edge SDK: record, save, replay"]
104
+ CP["Control plane<br/>storage, query, visualization"]
105
+ T["TokenOps<br/>governance"]
106
+
107
+ C -->|imports| P
108
+ CP -->|imports| P
109
+ T -->|imports| P
110
+ C -->|"envelopes over HTTP"| CP
111
+ T -->|"reads cost data"| CP
112
+ ```
113
+
114
+ The control plane owns the schema, and this package is where that schema is defined and shared.
115
+ Chronicle never talks to a database. It sends envelopes to the control plane, which keeps its own
116
+ storage layout and maps from these models.
117
+
118
+ ## 🎯 Scope
119
+
120
+ | In scope | Out of scope |
121
+ |---|---|
122
+ | `Trace`, `Span`, `Envelope` and their `llm` and `tool` payload variants | Storage, HTTP clients or servers |
123
+ | The `traceparent` carrier, id generation and validation | Business logic (pricing, policy, replay matching) |
124
+ | Enumerations and well-known metadata keys | Visualization or export (the control plane maps to OpenTelemetry) |
125
+ | Committed JSON Schema for every model | HTTP request and response wrappers (the control plane owns them, [ADR 0003](docs/adr/0003-api-models-live-in-control-plane.md)) |
126
+ | | Anything that performs I/O |
127
+
128
+ ## 🔖 Versioning
129
+
130
+ SemVer for the package, plus a `schema_version` (`major.minor`) on every payload.
131
+
132
+ - **Additive-only within a major.** New optional fields are allowed. A new enum member is
133
+ additive for the writer, but older readers reject it, so **consumers upgrade before emitters**.
134
+ - **A breaking change is a new major.** The control plane accepts the current and previous major.
135
+ - **Pre-1.0:** pin the exact minor. From 1.0: `>=1.2,<2`.
136
+
137
+ Full policy: [docs/versioning.md](docs/versioning.md).
138
+
139
+ ## 🛠 Development
140
+
141
+ Uses [uv](https://docs.astral.sh/uv/).
142
+
143
+ ```bash
144
+ uv sync # environment with the dev group
145
+ uv run pytest --cov # tests
146
+ uv run ruff check . && uv run ruff format --check .
147
+ uv run mypy # strict type check
148
+ uv build # sdist and wheel
149
+ ```
150
+
151
+ ## 🗺 Roadmap
152
+
153
+ 1. ✅ Repository scaffold
154
+ 2. ✅ `Trace`, `Span`, `Envelope`, the `llm` and `tool` payload variants, enums, ids
155
+ 3. ✅ The `traceparent` carrier
156
+ 4. ✅ Committed JSON Schema and the CI drift check
157
+ 5. First release (0.1.0): see [RELEASING.md](RELEASING.md)
158
+
159
+ ## Reference
160
+
161
+ <details>
162
+ <summary><b>Project structure</b></summary>
163
+
164
+ ```
165
+ src/agentplane_primitives/ # installable package (typed; version in _version.py)
166
+ ├── enums/ # closed lists, one file each: kind, state, status, link type
167
+ ├── types/ # field types: id types, metadata key and label types
168
+ ├── models/ # the models: base class now; Trace, Span, Envelope to come
169
+ ├── utils/ # helper functions: id generation, reserved-key check (traceparent later)
170
+ └── schemas/ # generated JSON Schema, committed and drift-checked in CI
171
+ # (more models and the traceparent carrier arrive in later PRs)
172
+ docs/ # design notes and the versioning policy
173
+ tests/ # unit tests
174
+ .github/ # CI, release, dependency updates, templates
175
+ ```
176
+
177
+ </details>
178
+
179
+ <details>
180
+ <summary><b>More documentation</b></summary>
181
+
182
+ - [Design](docs/design.md): the entities and where they are specified
183
+ - [Versioning policy](docs/versioning.md)
184
+ - [Changelog](CHANGELOG.md): every change classified as compatible or breaking
185
+ - [Contributing](CONTRIBUTING.md) - [Releasing](RELEASING.md) - [Security](SECURITY.md)
186
+
187
+ </details>
188
+
189
+ ## 🛟 Support
190
+
191
+ | Need | Where |
192
+ |---|---|
193
+ | Bug | [Open an issue](https://github.com/theagentplane/primitives/issues) |
194
+ | Schema change | [Schema change proposal](https://github.com/theagentplane/primitives/issues/new?template=schema_change.yml) |
195
+ | Security issue | [SECURITY.md](SECURITY.md) |
196
+ | Real-time help | [Slack](https://join.slack.com/t/theagentplane/shared_invite/zt-47lqx2xtc-0idr1cuLNJ_JDTgqxDiUsg) |
197
+ | Talk it through | [Office hours](https://calendly.com/theagentplane/theagentplane) |
198
+
199
+ ## Contributors
200
+
201
+ Thanks to everyone who has contributed.
202
+
203
+ [![Contributors](https://contrib.rocks/image?repo=theagentplane/primitives)](https://github.com/theagentplane/primitives/graphs/contributors)
204
+
205
+ ---
206
+
207
+ <div align="center">
208
+
209
+ [Back to top](#agentplane-primitives)
210
+
211
+ </div>
@@ -0,0 +1,185 @@
1
+ <div align="center">
2
+
3
+ # AgentPlane Primitives
4
+
5
+ **One schema for every agent trace.**<br>
6
+ <sub>Shared, versioned Trace, Span and Envelope models for Chronicle, the control plane and TokenOps.</sub>
7
+
8
+ [![CI](https://github.com/theagentplane/primitives/actions/workflows/ci.yml/badge.svg)](https://github.com/theagentplane/primitives/actions/workflows/ci.yml)
9
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://github.com/theagentplane/primitives)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
11
+ [![Typed](https://img.shields.io/badge/typing-strict-informational.svg)](https://peps.python.org/pep-0561/)
12
+ [![GitHub stars](https://img.shields.io/github/stars/theagentplane/primitives?style=social)](https://github.com/theagentplane/primitives/stargazers)
13
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-0A66C2?logo=linkedin&logoColor=white)](https://www.linkedin.com/company/the-agent-plane/)
14
+
15
+ <sub>Built by <b><a href="https://www.linkedin.com/in/susheemkoul/">Susheem Koul</a></b> and <b><a href="https://www.linkedin.com/in/tisha-chawla/">Tisha Chawla</a></b></sub>
16
+
17
+ <br>
18
+
19
+ [Core features](#-core-features) · [Quickstart](#-quickstart) · [How it fits](#-how-it-fits) · [Scope](#-scope) · [Versioning](#-versioning) · [Development](#-development) · [Support](#-support)
20
+
21
+ </div>
22
+
23
+ > ### 🚧 Pre-alpha
24
+ >
25
+ > This release is the repository scaffold. The models land in follow-up releases (see the
26
+ > [roadmap](#-roadmap)). Everything under *Core features* describes the
27
+ > [design](docs/design.md) these releases implement.
28
+
29
+ ## ✨ Core features
30
+
31
+ Chronicle records what an agent did, the control plane stores and shows it, and TokenOps reads
32
+ it to govern spend. Those three only work together if they agree on the shape of the data.
33
+ This package is that agreement, and nothing else.
34
+
35
+ | | |
36
+ |---|---|
37
+ | **Three tiers** | A `Trace` is one request across services, a `Span` is one service's handling of it, an `Envelope` is one boundary crossing inside the span. |
38
+ | **One definition, three repos** | Chronicle, the control plane and TokenOps import the same models. None defines its own copy. |
39
+ | **Closed enums** | `kind`, `state`, `status` and the other enumerations are closed sets. A new value is a deliberate schema change. |
40
+ | **Additive-only versioning** | SemVer for the package plus a `schema_version` on every payload. Nothing breaks within a major version. |
41
+ | **W3C `traceparent` carrier** | Parse and format the trace-context header so a trace follows a request across services. |
42
+ | **No I/O, one dependency** | Data and validation only, on pydantic. No network, no disk, no business logic. |
43
+ | **Contract you can read** | Generated JSON Schema, committed and checked in CI, for anything that is not Python. |
44
+
45
+ ## 🚀 Quickstart
46
+
47
+ Requires Python 3.10+. The package is typed ([PEP 561](https://peps.python.org/pep-0561/)).
48
+
49
+ ```bash
50
+ pip install agentplane-primitives # once the first release is published
51
+ ```
52
+
53
+ Until then, install from source:
54
+
55
+ ```bash
56
+ git clone https://github.com/theagentplane/primitives.git
57
+ cd primitives
58
+ pip install -e .
59
+ python -c "import agentplane_primitives as p; print(p.__version__)"
60
+ ```
61
+
62
+ ### When you need more
63
+
64
+ | You want to | Go to |
65
+ |---|---|
66
+ | Understand the entities and why there are three tiers | [Design](docs/design.md) |
67
+ | Know what may change between versions | [Versioning policy](docs/versioning.md) |
68
+ | Propose a new field or enum value | [Schema change proposal](https://github.com/theagentplane/primitives/issues/new?template=schema_change.yml) |
69
+ | Add a model | [Contributing](CONTRIBUTING.md) |
70
+ | Publish a release | [Releasing](RELEASING.md) |
71
+
72
+ ## 🧩 How it fits
73
+
74
+ ```mermaid
75
+ flowchart LR
76
+ P["primitives<br/>Trace · Span · Envelope"]
77
+ C["Chronicle<br/>edge SDK: record, save, replay"]
78
+ CP["Control plane<br/>storage, query, visualization"]
79
+ T["TokenOps<br/>governance"]
80
+
81
+ C -->|imports| P
82
+ CP -->|imports| P
83
+ T -->|imports| P
84
+ C -->|"envelopes over HTTP"| CP
85
+ T -->|"reads cost data"| CP
86
+ ```
87
+
88
+ The control plane owns the schema, and this package is where that schema is defined and shared.
89
+ Chronicle never talks to a database. It sends envelopes to the control plane, which keeps its own
90
+ storage layout and maps from these models.
91
+
92
+ ## 🎯 Scope
93
+
94
+ | In scope | Out of scope |
95
+ |---|---|
96
+ | `Trace`, `Span`, `Envelope` and their `llm` and `tool` payload variants | Storage, HTTP clients or servers |
97
+ | The `traceparent` carrier, id generation and validation | Business logic (pricing, policy, replay matching) |
98
+ | Enumerations and well-known metadata keys | Visualization or export (the control plane maps to OpenTelemetry) |
99
+ | Committed JSON Schema for every model | HTTP request and response wrappers (the control plane owns them, [ADR 0003](docs/adr/0003-api-models-live-in-control-plane.md)) |
100
+ | | Anything that performs I/O |
101
+
102
+ ## 🔖 Versioning
103
+
104
+ SemVer for the package, plus a `schema_version` (`major.minor`) on every payload.
105
+
106
+ - **Additive-only within a major.** New optional fields are allowed. A new enum member is
107
+ additive for the writer, but older readers reject it, so **consumers upgrade before emitters**.
108
+ - **A breaking change is a new major.** The control plane accepts the current and previous major.
109
+ - **Pre-1.0:** pin the exact minor. From 1.0: `>=1.2,<2`.
110
+
111
+ Full policy: [docs/versioning.md](docs/versioning.md).
112
+
113
+ ## 🛠 Development
114
+
115
+ Uses [uv](https://docs.astral.sh/uv/).
116
+
117
+ ```bash
118
+ uv sync # environment with the dev group
119
+ uv run pytest --cov # tests
120
+ uv run ruff check . && uv run ruff format --check .
121
+ uv run mypy # strict type check
122
+ uv build # sdist and wheel
123
+ ```
124
+
125
+ ## 🗺 Roadmap
126
+
127
+ 1. ✅ Repository scaffold
128
+ 2. ✅ `Trace`, `Span`, `Envelope`, the `llm` and `tool` payload variants, enums, ids
129
+ 3. ✅ The `traceparent` carrier
130
+ 4. ✅ Committed JSON Schema and the CI drift check
131
+ 5. First release (0.1.0): see [RELEASING.md](RELEASING.md)
132
+
133
+ ## Reference
134
+
135
+ <details>
136
+ <summary><b>Project structure</b></summary>
137
+
138
+ ```
139
+ src/agentplane_primitives/ # installable package (typed; version in _version.py)
140
+ ├── enums/ # closed lists, one file each: kind, state, status, link type
141
+ ├── types/ # field types: id types, metadata key and label types
142
+ ├── models/ # the models: base class now; Trace, Span, Envelope to come
143
+ ├── utils/ # helper functions: id generation, reserved-key check (traceparent later)
144
+ └── schemas/ # generated JSON Schema, committed and drift-checked in CI
145
+ # (more models and the traceparent carrier arrive in later PRs)
146
+ docs/ # design notes and the versioning policy
147
+ tests/ # unit tests
148
+ .github/ # CI, release, dependency updates, templates
149
+ ```
150
+
151
+ </details>
152
+
153
+ <details>
154
+ <summary><b>More documentation</b></summary>
155
+
156
+ - [Design](docs/design.md): the entities and where they are specified
157
+ - [Versioning policy](docs/versioning.md)
158
+ - [Changelog](CHANGELOG.md): every change classified as compatible or breaking
159
+ - [Contributing](CONTRIBUTING.md) - [Releasing](RELEASING.md) - [Security](SECURITY.md)
160
+
161
+ </details>
162
+
163
+ ## 🛟 Support
164
+
165
+ | Need | Where |
166
+ |---|---|
167
+ | Bug | [Open an issue](https://github.com/theagentplane/primitives/issues) |
168
+ | Schema change | [Schema change proposal](https://github.com/theagentplane/primitives/issues/new?template=schema_change.yml) |
169
+ | Security issue | [SECURITY.md](SECURITY.md) |
170
+ | Real-time help | [Slack](https://join.slack.com/t/theagentplane/shared_invite/zt-47lqx2xtc-0idr1cuLNJ_JDTgqxDiUsg) |
171
+ | Talk it through | [Office hours](https://calendly.com/theagentplane/theagentplane) |
172
+
173
+ ## Contributors
174
+
175
+ Thanks to everyone who has contributed.
176
+
177
+ [![Contributors](https://contrib.rocks/image?repo=theagentplane/primitives)](https://github.com/theagentplane/primitives/graphs/contributors)
178
+
179
+ ---
180
+
181
+ <div align="center">
182
+
183
+ [Back to top](#agentplane-primitives)
184
+
185
+ </div>
@@ -0,0 +1,55 @@
1
+ # 0001. Record architecture decisions
2
+
3
+ | Field | Value |
4
+ |---|---|
5
+ | Status | Accepted |
6
+ | Date | 2026-10-05 |
7
+ | Deciders | Susheem Koul, Tisha Chawla |
8
+
9
+ ## Context
10
+
11
+ Four repositories (chronicle, primitives, control-plane, tokenops) now evolve together and share
12
+ contracts. Decisions are made in conversations, pull request threads and long design documents,
13
+ and the reasoning is hard to find afterwards. New contributors, and AI coding agents working in
14
+ these repositories, have no reliable way to learn why something is built the way it is, so they
15
+ can unknowingly undo a deliberate choice.
16
+
17
+ ## Options considered
18
+
19
+ ### Option A: keep decisions inside design documents and pull requests
20
+
21
+ - Good: no new process.
22
+ - Bad: reasoning is scattered, mixed with implementation detail, and edited over time, so the
23
+ record of what was decided and when is lost.
24
+
25
+ ### Option B: one ADR per decision, stored in each repository
26
+
27
+ - Good: small, dated, reviewable records next to the code; easy for agents to read; history
28
+ shows what changed and why.
29
+ - Bad: a little writing discipline is needed, and cross-repository decisions need a rule about
30
+ where they live.
31
+
32
+ ## Decision
33
+
34
+ We will record architecture decisions as ADRs in `docs/adr/` of each repository, using the
35
+ template in this folder. Cross-repository decisions are recorded in the repository that owns the
36
+ decision and linked from the others. AI coding agents are told to read the ADRs before changing
37
+ architecture and to follow `docs/adr/README.md` when asked to record a decision.
38
+
39
+ ## Consequences
40
+
41
+ - **Good:** decisions are findable and dated; superseded decisions stay visible.
42
+ - **Bad or risky:** ADRs go stale if nobody writes them, so writing one is part of making a
43
+ qualifying decision, not a follow-up.
44
+ - **Follow-ups:** backfill ADRs for the decisions already taken in the Chronicle technical
45
+ design document where they matter most.
46
+
47
+ ## Impact on other repositories
48
+
49
+ The same folder, template and agent instructions are added to chronicle, primitives,
50
+ control-plane and tokenops.
51
+
52
+ ## Links
53
+
54
+ - [How to write an ADR](README.md)
55
+ - [Template](template.md)
@@ -0,0 +1,60 @@
1
+ # 0002. Define envelope `kind` as a closed enum with two members
2
+
3
+ | Field | Value |
4
+ |---|---|
5
+ | Status | Accepted |
6
+ | Date | 2026-10-06 |
7
+ | Deciders | Susheem Koul, Tisha Chawla |
8
+
9
+ ## Context
10
+
11
+ Every envelope has a `kind` that selects the shape of its input and output (design sections 2.3
12
+ and 2.9). In Chronicle 0.5.0, `kind` is a free string, and `router` and `custom` are in use
13
+ alongside `llm` and `tool`. Consumers such as TokenOps read the envelope by kind, and replay
14
+ needs to know how to handle each one. A router is either an LLM call or, if it is a plain
15
+ function, a tool; delegating work to another agent is an outbound call, which is a tool envelope
16
+ (the link between the two services is carried by `traceparent`).
17
+
18
+ ## Options considered
19
+
20
+ ### Option A: keep `kind` a free string
21
+
22
+ What 0.5.0 does today.
23
+
24
+ - Good: unchanged from 0.5.0.
25
+ - Bad: it allows values such as `router` and `custom`, which the design retires (section 2.3).
26
+
27
+ ### Option B: closed enum defined in this package
28
+
29
+ `kind` is `llm` or `tool`. Any other value is rejected at validation.
30
+
31
+ - Good: a value outside the enum is rejected at validation (section 2.3).
32
+ - Bad: adding a kind is a schema change made in this package (section 2.8).
33
+
34
+ ## Decision
35
+
36
+ We will define `kind` as a closed enum in this package with the members `llm` and `tool`, and
37
+ reject every other value, including custom and unregistered kinds. `router` and `custom` from
38
+ 0.5.0 are retired; both become `tool`.
39
+
40
+ ## Consequences
41
+
42
+ - **Good:** one definition of `kind`, shared by Chronicle, the control plane and TokenOps.
43
+ - **Bad or risky:** a new kind is additive for the writer, but a reader on an older minor rejects
44
+ it, so consumers must upgrade before emitters (`docs/versioning.md`). Users cannot invent their
45
+ own kinds.
46
+ - **Follow-ups:** the input and output variants selected by `kind` arrive with the envelope
47
+ (tool first, then llm).
48
+
49
+ ## Impact on other repositories
50
+
51
+ - **chronicle:** declaring a boundary with any other kind fails at declaration time; `router`
52
+ and `custom` become `tool` (design section 12.3).
53
+ - **control-plane:** validates ingested envelopes against this enum.
54
+ - **tokenops:** `delegate` is removed from its list of observation kinds, leaving `llm | tool`.
55
+
56
+ ## Links
57
+
58
+ - Design: `docs/rfcs/chronicle-technical-design.md` in chronicle, sections 2.3 and 2.9, decision
59
+ 12.
60
+ - [Versioning policy](../versioning.md)
@@ -0,0 +1,68 @@
1
+ # 0003. Keep HTTP request and response wrappers out of primitives
2
+
3
+ | Field | Value |
4
+ |---|---|
5
+ | Status | Accepted |
6
+ | Date | 2026-10-06 |
7
+ | Deciders | Susheem Koul, Tisha Chawla |
8
+
9
+ ## Context
10
+
11
+ The Chronicle technical design (sections 2.8 and 10.1, and the layer table in section 1.1) lists
12
+ "the API request and response models" as part of this package, next to Trace, Span and
13
+ Envelope. Decision 9 of that design says the control plane owns the schema and that Chronicle
14
+ "must not depend on server code".
15
+
16
+ Trace, Span and Envelope are the records the whole system stores and passes around. They are
17
+ data, not requests. The control plane will use them as the body of its requests and responses,
18
+ while the endpoints, status codes and the rest of the HTTP layer are its own concern.
19
+
20
+ ## Options considered
21
+
22
+ ### Option A: API models stay in primitives (the design as written)
23
+
24
+ - Good: matches the design as written (sections 1.1, 2.8 and 10.1).
25
+ - Bad: it treats HTTP request and response wrappers as part of the data model, when the
26
+ maintainers consider Trace, Span and Envelope to be data and not request objects.
27
+
28
+ ### Option B: the control plane owns all API models, and Chronicle depends on primitives through it
29
+
30
+ - Good: nothing HTTP-specific in primitives.
31
+ - Bad: Chronicle would depend on server code, which conflicts with decision 9 of the design.
32
+
33
+ ### Option C: primitives holds only the entities; the control plane owns the HTTP wrappers
34
+
35
+ Requests and responses reuse primitives types as their bodies (an upsert-span body is a `Span`; a
36
+ batch of envelopes is a list of `Envelope`). Wrappers that exist only because of the HTTP API
37
+ (the write result and the error body) belong to the control plane. Chronicle imports primitives
38
+ directly.
39
+
40
+ - Good: primitives stays about the data, and Chronicle depends on primitives directly.
41
+ - Bad: Chronicle must read the write result and error body without a shared model, so it needs a
42
+ few lines of its own code and a contract test against the control plane.
43
+
44
+ ## Decision
45
+
46
+ We will take Option C. Primitives defines the entities, ids, enums, metadata rules, the
47
+ `traceparent` carrier and the committed JSON Schema, and no HTTP request or response wrappers.
48
+
49
+ ## Consequences
50
+
51
+ - **Good:** a smaller package: primitives holds data only.
52
+ - **Bad or risky:** the result and error shapes are defined in one repository and read in
53
+ another, so drift is possible until a contract test exists. If those shapes grow, moving them
54
+ into primitives later is an additive change.
55
+ - **Follow-ups:** the planned primitives PR for API models is dropped. The control plane
56
+ defines the wrappers; Chronicle adds a contract test.
57
+
58
+ ## Impact on other repositories
59
+
60
+ - **chronicle:** the technical design (sections 1.1, 2.8, 10.1) is updated to match. The client
61
+ imports primitives for entities and parses the write result and error body itself.
62
+ - **control-plane:** defines the HTTP wrappers and reuses primitives entities as bodies.
63
+ - **tokenops:** none.
64
+
65
+ ## Links
66
+
67
+ - Design: `docs/rfcs/chronicle-technical-design.md` in chronicle, sections 1.1, 2.8, 10.1 and
68
+ decision 9.