agent-tokenops 0.1.0__py3-none-any.whl

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 (63) hide show
  1. agent_tokenops-0.1.0.dist-info/METADATA +305 -0
  2. agent_tokenops-0.1.0.dist-info/RECORD +63 -0
  3. agent_tokenops-0.1.0.dist-info/WHEEL +5 -0
  4. agent_tokenops-0.1.0.dist-info/licenses/LICENSE.txt +21 -0
  5. agent_tokenops-0.1.0.dist-info/top_level.txt +1 -0
  6. tokenops/__init__.py +12 -0
  7. tokenops/config/__init__.py +3 -0
  8. tokenops/config/default.yaml +37 -0
  9. tokenops/config/loader.py +30 -0
  10. tokenops/control/__init__.py +111 -0
  11. tokenops/control/attribution.py +185 -0
  12. tokenops/control/boundary.py +145 -0
  13. tokenops/control/client.py +146 -0
  14. tokenops/control/config.py +162 -0
  15. tokenops/control/context.py +136 -0
  16. tokenops/control/core.py +329 -0
  17. tokenops/control/crossing.py +99 -0
  18. tokenops/control/engine.py +293 -0
  19. tokenops/control/http.py +126 -0
  20. tokenops/control/integration.py +375 -0
  21. tokenops/control/ledger.py +297 -0
  22. tokenops/control/models.py +117 -0
  23. tokenops/control/policies/__init__.py +33 -0
  24. tokenops/control/policies/_util.py +89 -0
  25. tokenops/control/policies/concurrency_cap.py +80 -0
  26. tokenops/control/policies/context_compaction.py +78 -0
  27. tokenops/control/policies/cost_budget.py +68 -0
  28. tokenops/control/policies/cost_guard.py +98 -0
  29. tokenops/control/policies/output_runaway.py +94 -0
  30. tokenops/control/policies/pre_call_worst_case.py +103 -0
  31. tokenops/control/policies/progress_guard.py +105 -0
  32. tokenops/control/policies/step_cap.py +57 -0
  33. tokenops/control/policies/tool_fix.py +100 -0
  34. tokenops/control/policies/tool_output_cap.py +88 -0
  35. tokenops/control/policies/trajectory_hint.py +254 -0
  36. tokenops/control/pricing.py +68 -0
  37. tokenops/control/propagate.py +46 -0
  38. tokenops/control/store.py +717 -0
  39. tokenops/control/trajectory/__init__.py +15 -0
  40. tokenops/control/trajectory/compress.py +43 -0
  41. tokenops/control/trajectory/enqueue.py +64 -0
  42. tokenops/control/trajectory/gates.py +35 -0
  43. tokenops/control/trajectory/hint.py +75 -0
  44. tokenops/control/trajectory/scope.py +69 -0
  45. tokenops/control/trajectory/serialize.py +66 -0
  46. tokenops/control/trajectory/worker.py +29 -0
  47. tokenops/env.py +22 -0
  48. tokenops/providers/__init__.py +4 -0
  49. tokenops/providers/anthropic.py +28 -0
  50. tokenops/providers/factory.py +39 -0
  51. tokenops/providers/openai.py +54 -0
  52. tokenops/providers/types.py +10 -0
  53. tokenops/server/__init__.py +5 -0
  54. tokenops/server/__main__.py +26 -0
  55. tokenops/server/app.py +38 -0
  56. tokenops/ui/__init__.py +0 -0
  57. tokenops/ui/app.py +28 -0
  58. tokenops/ui/run_detail.py +120 -0
  59. tokenops/ui/store_client.py +25 -0
  60. tokenops/ui/theme.py +145 -0
  61. tokenops/ui/views/__init__.py +0 -0
  62. tokenops/ui/views/admin.py +260 -0
  63. tokenops/ui/views/dashboard.py +146 -0
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-tokenops
3
+ Version: 0.1.0
4
+ Summary: TokenOps control plane and SDK for run-aware agent token governance
5
+ Author: Susheem Koul, Tisha Chawla
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/theagentplane/tokenops
8
+ Project-URL: Repository, https://github.com/theagentplane/tokenops
9
+ Project-URL: Issues, https://github.com/theagentplane/tokenops/issues
10
+ Project-URL: Changelog, https://github.com/theagentplane/tokenops/blob/main/CHANGELOG.md
11
+ Keywords: llm,agents,governance,token-budget,multi-agent,control-plane,cost-control
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: System :: Systems Administration
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE.txt
23
+ Requires-Dist: agent-chronicle>=0.1.1
24
+ Requires-Dist: openai>=1.0
25
+ Requires-Dist: anthropic>=0.40
26
+ Requires-Dist: pyyaml>=6.0
27
+ Requires-Dist: python-dotenv>=1.0
28
+ Requires-Dist: streamlit>=1.30
29
+ Requires-Dist: httpx>=0.27
30
+ Requires-Dist: fastapi>=0.115
31
+ Requires-Dist: uvicorn>=0.32
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=8.0; extra == "dev"
34
+ Requires-Dist: build>=1.2; extra == "dev"
35
+ Requires-Dist: twine>=6.0; extra == "dev"
36
+ Provides-Extra: examples
37
+ Requires-Dist: ddgs>=9.0; extra == "examples"
38
+ Requires-Dist: langchain-core>=0.3; extra == "examples"
39
+ Requires-Dist: langchain-openai>=0.2; extra == "examples"
40
+ Requires-Dist: langchain-anthropic>=0.2; extra == "examples"
41
+ Dynamic: license-file
42
+
43
+ <div align="center">
44
+
45
+ # TokenOps
46
+
47
+ **Run-aware token governance for multi-agent systems.**<br>
48
+ Cap spend and steer behavior across a whole agent workflow — not per request — with a shared ledger and in-path enforcement.
49
+
50
+ [![CI](https://github.com/theagentplane/tokenops/actions/workflows/test.yml/badge.svg)](https://github.com/theagentplane/tokenops/actions/workflows/test.yml)
51
+ [![PyPI](https://img.shields.io/pypi/v/agent-tokenops.svg)](https://pypi.org/project/agent-tokenops/)
52
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://github.com/theagentplane/tokenops)
53
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.txt)
54
+ [![Status](https://img.shields.io/badge/status-0.x%20%7C%20draft-7B61FF?style=flat-square)](https://semver.org/)
55
+ [![Stars](https://img.shields.io/github/stars/theagentplane/tokenops?style=flat&color=yellow)](https://github.com/theagentplane/tokenops/stargazers)
56
+
57
+ <br>
58
+
59
+ <img src="https://raw.githubusercontent.com/theagentplane/tokenops/main/examples/demo-assets/videos/02_governance_on_budget_cap.png" alt="TokenOps Dashboard: governance halt when worst-case cost exceeds remaining run budget" width="720" />
60
+
61
+ </div>
62
+
63
+ <br>
64
+
65
+ TokenOps is a **control plane + SDK** for agent stacks. Entry agents register a run; every LLM and tool crossing shares one `run_id` and one ledger. Policies can halt, mutate, or inject before the next call executes — so a research → summarize → review pipeline stays inside a single budget even across processes.
66
+
67
+ **[Why](#why-tokenops) · [Architecture](#architecture) · [Install](#install) · [Quick start](#quick-start) · [Demos](#demos) · [Comparison](#how-tokenops-compares) · [Make targets](#make-targets) · [Roadmap](#roadmap)**
68
+
69
+ ## Why TokenOps
70
+
71
+ - **Govern the run, not the request.** One `run_id` spans every model, tool, and A2A hop in a workflow.
72
+ - **Shared ledger across processes.** Spend, inflight, and halt live in SQLite so multi-agent stacks cannot each burn the full cap locally.
73
+ - **In-path enforcement.** `wrap_complete` runs detect → decide → apply *before* the next LLM call; Chronicle `@boundary` + a crossing hook ingest tool spend.
74
+ - **Steer or stop.** Actuators: `HALT` · `MUTATE` · `INJECT` · reject/queue — not just post-hoc analytics.
75
+ - **Batteries included.** Control plane (`:7700`), Admin + Dashboard UI, ten seeded policies, and runnable A2A benches (two-agent, triad, LangChain brief).
76
+
77
+ ## Architecture
78
+
79
+ TokenOps is two layers that share one artifact, the **run**: a control plane that registers runs and stores budgets/policies, and an in-process SDK that enforces at every boundary crossing.
80
+
81
+ ```mermaid
82
+ flowchart LR
83
+ subgraph PLANE["Control plane (:7700)"]
84
+ R["POST /v1/runs"] --> DB[("SQLite TOKENOPS_DB<br/>registrations · budgets · policies · ledger")]
85
+ UI["Admin + Dashboard"] --> DB
86
+ end
87
+
88
+ subgraph AGENTS["Agent processes (SDK)"]
89
+ E["Entry agent<br/>entry_task_run_scope"] -->|"register_run"| R
90
+ E -->|"X-TokenOps-Run-Id"| D["Downstream agents"]
91
+ E & D -->|"wrap_complete"| G["Governor<br/>pre_call → detect → decide → apply"]
92
+ E & D -->|"@boundary + crossing hook"| G
93
+ G --> L["Shared ledger<br/>(same run_id)"]
94
+ end
95
+
96
+ L --> DB
97
+ DB -->|"governance_config_for"| G
98
+ ```
99
+
100
+ | Piece | Owns | Does not own |
101
+ |---|---|---|
102
+ | **Control plane** (`python -m tokenops.server`) | `POST /v1/runs`, shared SQLite, Admin/Dashboard | Agent loops, LLM calls, tools |
103
+ | **SDK (in agents)** | `wrap_complete`, ledger/policies, Chronicle crossing hook, run propagation | Ad-hoc run IDs; mounting `/v1/runs` when `TOKENOPS_URL` is set |
104
+
105
+ Chronicle records decision boundaries; TokenOps attaches as the cost/governance observer on live crossings. See [Chronicle](https://github.com/theagentplane/chronicle) for record-and-replay.
106
+
107
+ ## Install
108
+
109
+ ```bash
110
+ pip install agent-tokenops
111
+
112
+ # With example / bench extras (LangChain, ddgs):
113
+ pip install "agent-tokenops[examples]"
114
+
115
+ # From source (development):
116
+ pip install -e ".[dev,examples]"
117
+ ```
118
+
119
+ Requires Python 3.10+. PyPI name is `agent-tokenops`; import is still `tokenops`
120
+ (same pattern as Chronicle). See [`RELEASING.md`](RELEASING.md) for releases.
121
+
122
+ ## Quick start
123
+
124
+ ```bash
125
+ make install
126
+ cp .env.example .env # optional API keys for demos / your agents
127
+
128
+ make db-reset # optional: clean SQLite + seed governance from default.yaml
129
+ make run # control plane :7700 + Admin/Dashboard :8501
130
+ ```
131
+
132
+ Wire governance into an agent: register the run at the **entry**, wrap the LLM, and install the Chronicle crossing hook for tools.
133
+
134
+ ```python
135
+ from tokenops import ControlPlaneClient
136
+ from tokenops.control import (
137
+ wrap_complete,
138
+ entry_task_run_scope,
139
+ governance_scope,
140
+ install_crossing_hook,
141
+ )
142
+ from tokenops.providers import complete
143
+
144
+ install_crossing_hook() # once per process; Chronicle on_crossing → Governor.observe
145
+
146
+ client = ControlPlaneClient.from_env() # TOKENOPS_URL or embedded Store
147
+
148
+ # Entry agent: UI omits run_id; entry opens the run on the plane
149
+ with entry_task_run_scope(store, headers=headers, payload=payload, service="planner"):
150
+ with governance_scope(governor, attr, provider=..., model=...):
151
+ governed = wrap_complete(
152
+ governor, controls, attr,
153
+ provider=provider, model=model,
154
+ dispatch=complete, service="planner",
155
+ )
156
+ run_agent(..., complete_fn=governed)
157
+ ```
158
+
159
+ Point agents at the plane and share one DB:
160
+
161
+ ```bash
162
+ export TOKENOPS_URL=http://localhost:7700
163
+ export TOKENOPS_DB=tokenops.db # plane + all agents
164
+ make control-plane # :7700
165
+ make ui # Admin + Dashboard :8501
166
+ ```
167
+
168
+ Full integration checklist: [`.cursor/skills/integrate-tokenops/SKILL.md`](.cursor/skills/integrate-tokenops/SKILL.md) · field guide: [`docs/guides/field-guide-add-tokenops.md`](docs/guides/field-guide-add-tokenops.md).
169
+
170
+ ## Demos
171
+
172
+ Each bench is a multi-agent stack with a shared run ledger. Start the plane, agents, and Admin UI with one make target.
173
+
174
+ | Demo | Agents | Run |
175
+ |---|---|---|
176
+ | Two-agent | Research → Summarize | `make demo` |
177
+ | Triad | Planner → Researcher → Writer | `make demo-triad` |
178
+ | Brief | Scout → Analyst → Editor (LangChain) | `make demo-brief` |
179
+ | Bench UI | Chat + Simulator only | `make bench-ui` |
180
+
181
+ ```bash
182
+ make demo # plane + research/summarize + Admin UI
183
+ make demo-triad # plane + planner/researcher/writer
184
+ make demo-brief # plane + scout/analyst/editor
185
+ ```
186
+
187
+ Docker:
188
+
189
+ ```bash
190
+ docker compose up --build
191
+ # optional UI: docker compose --profile ui up --build
192
+ # two-agent stack:
193
+ docker compose -f docker-compose.examples.yml up --build
194
+ ```
195
+
196
+ See [`examples/README.md`](examples/README.md) and [`docs/control-plane-deploy.md`](docs/control-plane-deploy.md).
197
+
198
+ ## How TokenOps compares
199
+
200
+ TokenOps is not a gateway or a tracing dashboard. It governs the **run** — a full agent workflow — and sits alongside the tools you already use for routing and observability.
201
+
202
+ | | TokenOps | LiteLLM / Portkey / AI Gateway | Langfuse |
203
+ |---|:---:|:---:|:---:|
204
+ | Primary focus | Run (stateful) | Request | Trace (observe) |
205
+ | Multi-agent workflow as one unit | Yes | No | Manual stitch |
206
+ | Budget enforcement in-path | Yes (run-aware) | Yes (key/team) | No (analytics) |
207
+ | Steer next call (mutate / inject) | Yes | Routing / fallbacks | No |
208
+ | Shared ledger across agent processes | Yes | N/A | N/A |
209
+
210
+ What this does **not** do: replace your LLM gateway, replace Chronicle-style record-and-replay, or host a SaaS control plane for you. Fail-closed integrity (refuse on missing registration) is optional and upcoming.
211
+
212
+ Longer table with logos: [`docs/product/comparison.md`](docs/product/comparison.md).
213
+
214
+ ## Make targets
215
+
216
+ <details>
217
+ <summary>Command reference</summary>
218
+
219
+ | Target | Role |
220
+ |--------|------|
221
+ | `make install` | Editable install with dev + examples extras |
222
+ | `make dist` / `check-dist` | Build sdist+wheel / `twine check` |
223
+ | `make control-plane` | Standalone plane (`python -m tokenops.server`) on `:7700` |
224
+ | `make ui` | Admin + Dashboard on `:8501` |
225
+ | `make run` | Plane + Admin/Dashboard |
226
+ | `make demo` / `demo-triad` / `demo-brief` | Runnable A2A stacks |
227
+ | `make bench-ui` | Chat + Simulator |
228
+ | `make db-reset` | Clear SQLite + reseed from `TOKENOPS_CONFIG` |
229
+ | `make stop` | Kill listeners on `:7700` / `:8501` |
230
+
231
+ </details>
232
+
233
+ ## Environment variables
234
+
235
+ | Variable | Purpose |
236
+ |---|---|
237
+ | `TOKENOPS_URL` | Remote plane base URL (e.g. `http://localhost:7700`) → HTTP `register_run` |
238
+ | `TOKENOPS_EMBEDDED` | Set to `1` to force in-process `Store` (tests / single-process) |
239
+ | `TOKENOPS_DB` | SQLite path shared by plane + agents |
240
+ | `TOKENOPS_CONFIG` | YAML for governance seed (core: `src/tokenops/config/default.yaml`) |
241
+
242
+ Production / multi-process: set `TOKENOPS_URL`; agents must **not** mount `/v1/runs`. Tests: `TOKENOPS_EMBEDDED=1` (or omit URL).
243
+
244
+ ## Project structure
245
+
246
+ Only `src/tokenops/` is the installable package. Demos and benches stay under `examples/`.
247
+
248
+ ```
249
+ src/tokenops/ # installable package
250
+ ├── server/ # control plane (:7700, POST /v1/runs)
251
+ ├── control/ # SDK: ledger, policies, wrap_complete, crossing hook
252
+ ├── providers/ # OpenAI / Anthropic complete dispatch
253
+ ├── config/ # default.yaml governance seed
254
+ └── ui/ # Admin + Dashboard (Streamlit)
255
+ examples/ # A2A benches (two-agent, triad, brief) + Chat/Simulator
256
+ benchmarking/ # MetaGPT / browser-use live harness
257
+ docs/ # architecture, policies, guides, product
258
+ tests/ # unit + e2e
259
+ ```
260
+
261
+ ## Roadmap
262
+
263
+ TokenOps is early (0.x). Near-term:
264
+
265
+ - User/tag segment-scoped budgets (machinery exists; seed is run-only today).
266
+ - Optional fail-closed mode on missing registration or exceeded budget.
267
+ - Remote observe / decide (fatter plane) for multi-host stacks.
268
+ - Documentation site.
269
+
270
+ Status of each control-plane job: [`CONTROL_PLANE.md`](CONTROL_PLANE.md). Ideas welcome via GitHub issues.
271
+
272
+ ## Documentation
273
+
274
+ - [Control plane status](CONTROL_PLANE.md)
275
+ - [Architecture](docs/architecture.md)
276
+ - [Run attribution](docs/run-attribution.md)
277
+ - [Control plane deploy](docs/control-plane-deploy.md)
278
+ - [Field guide](docs/guides/field-guide-add-tokenops.md)
279
+ - [Examples](examples/README.md)
280
+ - [Product: comparison](docs/product/comparison.md) · [shared ledger](docs/product/shared-ledger.md)
281
+
282
+ ## Contributing
283
+
284
+ Issues and PRs are welcome. Dev setup:
285
+
286
+ ```bash
287
+ make install
288
+ python -m pytest -q
289
+ ```
290
+
291
+ ## Contributors
292
+
293
+ Thanks to everyone who has contributed.
294
+
295
+ [![Contributors](https://contrib.rocks/image?repo=theagentplane/tokenops)](https://github.com/theagentplane/tokenops/graphs/contributors)
296
+
297
+ ---
298
+
299
+ If TokenOps saves you a runaway agent bill, please [⭐ star the repo](https://github.com/theagentplane/tokenops) so more people can find it.
300
+
301
+ <div align="center">
302
+
303
+ Built by Susheem Koul and Tisha Chawla
304
+
305
+ </div>
@@ -0,0 +1,63 @@
1
+ agent_tokenops-0.1.0.dist-info/licenses/LICENSE.txt,sha256=pflS2CCLsAIr6pIhUOZSJudBKOC5c0R-B4s5OcO3Lb4,1086
2
+ tokenops/__init__.py,sha256=F9jVo9QvXx-NrfbuLB2ZirWX0Y4_sw6l0Ork-SlKurg,300
3
+ tokenops/env.py,sha256=-97XzDyMajrkmRtu9ZyPT0t2JmfTuQKJZmqu4bcbyU0,510
4
+ tokenops/config/__init__.py,sha256=9NdrlHt040-ZKdU2u-VdtQXnW0HSSoR2pTbx7rSyhVA,92
5
+ tokenops/config/default.yaml,sha256=DbLQeb1OxwVU89OM8Xxfq7WLh1qmSQV2zhaW651yV1Y,956
6
+ tokenops/config/loader.py,sha256=5mMMvC_2S3Pt7NkXkm09o_8GHR9NmC8XLpu-TmNhy4A,824
7
+ tokenops/control/__init__.py,sha256=4eEUCHIf7yGr7fdfeZI6L5JQUk7rSecZye6uupgm7yY,3802
8
+ tokenops/control/attribution.py,sha256=kDyfjXyJOv8_Q-cGMAr-mDtwu9ms77oRaPcZhaHXnBc,6174
9
+ tokenops/control/boundary.py,sha256=8c9uaplqdKIXbEA3JlJn0dh6SV52jiEN0_DzaA1W20o,4586
10
+ tokenops/control/client.py,sha256=zTq-hsG_AGx3Y710nmv1ypZ95narMrL8G-Z4XUxoc-c,5014
11
+ tokenops/control/config.py,sha256=UF_LkpTOK4_viojr4wPHXqWEC3F2dR2g3p6lF6ORv4k,6732
12
+ tokenops/control/context.py,sha256=IiGuKhDPeOdaqPwDyPvA6h9SsEpt1Yl0pZCwWrAeEQM,3612
13
+ tokenops/control/core.py,sha256=EOXEdFjZeehUxiX2W15wBOs3VB9WWKSl4KzrxS-CpBw,11809
14
+ tokenops/control/crossing.py,sha256=C7Wc5yDLuN7JM63UI3ZTLa5pRvNgaXQzN8O2_fRS6Qk,3323
15
+ tokenops/control/engine.py,sha256=PoJ9G2LGnj8UE6oSrTmxEzSQxDm_3iSRL9n5ah4WUZM,12164
16
+ tokenops/control/http.py,sha256=tl3Xvr-Duhb6Z7ayAkT1A_gHTaOEoD9W0Io50oU4HFE,4460
17
+ tokenops/control/integration.py,sha256=sh5a577c7NqAHugVAGj6a06iWcXw22bSTmixSako38Y,13211
18
+ tokenops/control/ledger.py,sha256=azouZ8F67Ki-IAdl0qAr2JHC8xj9fhy7RrzjAZfmZ1Q,12421
19
+ tokenops/control/models.py,sha256=a55xCutw7lFyXjAdBpfqNa50ZvSGxtShFJVgWzUe3qA,3686
20
+ tokenops/control/pricing.py,sha256=k8DRnAx7hEQU8Gfcl4BcqWSJNbGlGHgUhbvxrZ_pi1M,2521
21
+ tokenops/control/propagate.py,sha256=rIbgugNL0E8VtoGTBzLudivee6gspx4eS9_h-LKnOfc,1458
22
+ tokenops/control/store.py,sha256=WupP0vkYgvZZvEw1HWGaUnZEd0f43zReRdzKzE80v5A,28726
23
+ tokenops/control/policies/__init__.py,sha256=ockfgVmW8IQZUPF5KlSib2RElWZSUhVFO7SWUWDszGo,812
24
+ tokenops/control/policies/_util.py,sha256=yLCepRFcI24grWlLrYBTCTo2EQjUgc2_Q2jukyrCwxw,2969
25
+ tokenops/control/policies/concurrency_cap.py,sha256=EcY6_ayeXfNoyDUqZlZS-px-F2PykOze-PuLn81zPPk,2942
26
+ tokenops/control/policies/context_compaction.py,sha256=nlrLOmG0TajyoJkijdReJkOjNYiRe4AX1a4A-Yn_efE,3335
27
+ tokenops/control/policies/cost_budget.py,sha256=CtwdJkPT2dfPbS2Tpq1VCqjvUBezJ8bQpS5vwEvBPq8,2475
28
+ tokenops/control/policies/cost_guard.py,sha256=cd4nENinLXkGgUHFPW9QN8RoAygcDKFG3uDIE3DFoPA,4019
29
+ tokenops/control/policies/output_runaway.py,sha256=UkmQJDFrfV5qZJdSEnRvC0rQAQ7OJGlWanRNpism7iA,3838
30
+ tokenops/control/policies/pre_call_worst_case.py,sha256=fs842tt4B0QS6p3vsEImKNx2pHG7nG6l2pCc1iShO6s,4411
31
+ tokenops/control/policies/progress_guard.py,sha256=tuVHHd__5khe-ToQOobBETtcYoRwSr8OpIPkp8wqb2Q,4490
32
+ tokenops/control/policies/step_cap.py,sha256=qEXDLCx7Xp2qveX-fiagdL5xeyevG0IM41Prc06xEr4,1781
33
+ tokenops/control/policies/tool_fix.py,sha256=z0_ZOPJUoqtEyYhYbJcE-9l_ssUPBspKb2hk5Hjw3FE,3754
34
+ tokenops/control/policies/tool_output_cap.py,sha256=aC9he9esKMZNHy6pT2QLVXj-Hjz7GjEZQQRN5KZQP10,3458
35
+ tokenops/control/policies/trajectory_hint.py,sha256=FA8nfOGuEpP1qfCPVySmnMtyj_0dC0_G6taPu_-Xruk,9071
36
+ tokenops/control/trajectory/__init__.py,sha256=iSpsn4ZUPUqFoHSA_bDGcAkbL7kpu7UmZkYfYgCRXrM,571
37
+ tokenops/control/trajectory/compress.py,sha256=rI75aR7vEYU01ZquPMaIIRxQ6QODwJbNeqbE61Iy8pc,1507
38
+ tokenops/control/trajectory/enqueue.py,sha256=ETq2Id_pnHLOr4gyq1Lt1E8si-WLn5OtBFzNnaFTj8I,2165
39
+ tokenops/control/trajectory/gates.py,sha256=FajuRbrVr9iUbcjf1WtE1sUL0FtVyDc3_cD1HB9-2Gc,1014
40
+ tokenops/control/trajectory/hint.py,sha256=b5rJFPQpLZYuTZwdUxMPNA76iOur43-6xeMHnY6momc,2391
41
+ tokenops/control/trajectory/scope.py,sha256=zZxt9z4-sz-ezzhTV9aS0uSHc0qRWRAMd5SfvqztvGQ,1796
42
+ tokenops/control/trajectory/serialize.py,sha256=oxBHyKhHlRnp8OybsrprMwjuatSK4wg0-hGnU91iMdI,1909
43
+ tokenops/control/trajectory/worker.py,sha256=nTpIJf5A7t0d7u_0jdC3JH3oju7M9aTr6wfsnVQFf8E,766
44
+ tokenops/providers/__init__.py,sha256=q65odkbUvGJ2y28j9E2NwJbRRTesVtjdcQCXISNs1JI,176
45
+ tokenops/providers/anthropic.py,sha256=uA0_0vbtQxmY3jnRZBRbQ1JKGUP_Pgw1eTR8ji_DwrQ,1101
46
+ tokenops/providers/factory.py,sha256=aLEGVNQf44uQDv8MKsCC-Af5fs5uU7uVUC9Dzz1RHAQ,1898
47
+ tokenops/providers/openai.py,sha256=BHJbOkYr3j15SSfPo_iu8oUtmFD9sCrP20RHKI0zsDQ,2549
48
+ tokenops/providers/types.py,sha256=hYwEhL1FIsM7VXR5zHbeXGOBULDP4eWzlRfpgepu06o,174
49
+ tokenops/server/__init__.py,sha256=jNWsprfEaSGrAeYISIuXX-M_hR9td4oy_P5PRAp9o20,124
50
+ tokenops/server/__main__.py,sha256=gm3oqpJit2csUb4ZG4rH2ZAJV4F6evWot0Go_6lR4Eo,557
51
+ tokenops/server/app.py,sha256=qh7OuDpC7kTzhBpZNjTS0-aSUMpDiLREms3tfwtz-00,1164
52
+ tokenops/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ tokenops/ui/app.py,sha256=4RroN7XQTbiNrdnuu0X4NsKbYbB_677bzPqYKVXbUMs,600
54
+ tokenops/ui/run_detail.py,sha256=aLGwbQ-bWkm9-iVJvnG1qR8DVpyauLsqo0Dabi4Y-YQ,4197
55
+ tokenops/ui/store_client.py,sha256=X-WyVzUpd8LjmxLdYHKrs8BE5HU1QVefZdijG48recg,842
56
+ tokenops/ui/theme.py,sha256=sz-voqQ_RKPWdZ1Igx4eVL8YhIjWVnvKUx9vhBoC5OY,4306
57
+ tokenops/ui/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ tokenops/ui/views/admin.py,sha256=1KoxHmJlkFxZBdkCipiTiyfZNGjVOGFz6J0qav-Afpg,11342
59
+ tokenops/ui/views/dashboard.py,sha256=_slUKO5Oy6cigz3X3TylqPLPaWbUK3ZU6gUI3l2wJCs,5573
60
+ agent_tokenops-0.1.0.dist-info/METADATA,sha256=SbOHh3DozfdKt_qEdKSFdRh4VUZ50nrGW1YBEhKuo00,12774
61
+ agent_tokenops-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
62
+ agent_tokenops-0.1.0.dist-info/top_level.txt,sha256=MVWkw-7ZGkeuBcMqJ4Dp_r6ovKtrjxSnjLPOnAzE-qg,9
63
+ agent_tokenops-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -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 @@
1
+ tokenops
tokenops/__init__.py ADDED
@@ -0,0 +1,12 @@
1
+ """TokenOps control plane and SDK."""
2
+
3
+ from tokenops.env import load_env
4
+
5
+ load_env()
6
+
7
+ __version__ = "0.1.0"
8
+
9
+ # First-class SDK surface for agents / UIs talking to the plane.
10
+ from tokenops.control.client import ControlPlaneClient as ControlPlaneClient
11
+
12
+ __all__ = ["ControlPlaneClient", "__version__"]
@@ -0,0 +1,3 @@
1
+ from tokenops.config.loader import load_governance_yaml
2
+
3
+ __all__ = ["load_governance_yaml"]
@@ -0,0 +1,37 @@
1
+ # TokenOps control plane seed. Consumed by tokenops.control.build_governor / Store auto-seed.
2
+ # Budgets are spend caps bound to a segment; policies are the (detect, fix) templates.
3
+ governance:
4
+ budgets:
5
+ - id: run_llm_cap
6
+ limit_micros: 2000000 # $2.00 per run; null/omitted -> unlimited accumulator
7
+ dimension: run
8
+ policies:
9
+ cost_budget:
10
+ budget: run_llm_cap
11
+ pre_call_worst_case:
12
+ budget: run_llm_cap
13
+ default_max_output: 1024
14
+ step_cap:
15
+ max_steps: 20
16
+ concurrency_cap:
17
+ max_concurrent: 4
18
+ mode: reject
19
+ tool_fix:
20
+ registry: [search]
21
+ k: 3
22
+ tool_output_cap:
23
+ cap_tokens: 8000
24
+ progress_guard:
25
+ window: 6
26
+ repeats: 3
27
+ max_corrections: 2
28
+ cost_guard:
29
+ budget: run_llm_cap
30
+ threshold: 0.8
31
+ mode: minimize
32
+ context_compaction:
33
+ ctx_max: 100000
34
+ has_hook: false
35
+ output_runaway:
36
+ repeats: 4
37
+ max_retries: 2
@@ -0,0 +1,30 @@
1
+ """Governance YAML loading for the TokenOps control plane.
2
+
3
+ Agent/server bench config lives under ``examples.app_config``.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ from pathlib import Path
10
+
11
+ import yaml
12
+
13
+ DEFAULT_CONFIG = Path(__file__).resolve().parent / "default.yaml"
14
+
15
+
16
+ def _default_path() -> Path:
17
+ env = os.environ.get("TOKENOPS_CONFIG")
18
+ if env:
19
+ return Path(env)
20
+ return DEFAULT_CONFIG
21
+
22
+
23
+ def load_governance_yaml(path: Path | str | None = None) -> dict:
24
+ """Return the ``governance:`` block from the config YAML (budgets + policies)."""
25
+ config_path = Path(path) if path else _default_path()
26
+ if not config_path.exists():
27
+ return {}
28
+ data = yaml.safe_load(config_path.read_text()) or {}
29
+ block = data.get("governance")
30
+ return block if isinstance(block, dict) else {}
@@ -0,0 +1,111 @@
1
+ """TokenOps control layer (v1).
2
+
3
+ The Account (ledger) + Enforce (policies) half of the control plane. Consumes
4
+ attributed boundary crossings, records them, and decides: steer or stop.
5
+
6
+ Ten policies (delegation_cap dropped — fan-out is concurrency_cap, spend is
7
+ cost_budget / pre_call_worst_case), evaluated by moment:
8
+ pre_call : concurrency_cap, tool_fix, context_compaction, cost_guard, pre_call_worst_case
9
+ stream : output_runaway
10
+ observe : cost_budget, step_cap, tool_output_cap, progress_guard
11
+
12
+ Source of truth: docs/policies/ and docs/governance-policy.md. ``core.py`` is the
13
+ canonical vocabulary.
14
+ """
15
+
16
+ from tokenops.control.core import (
17
+ Action,
18
+ ActionKind,
19
+ Attribution,
20
+ BoundaryStep,
21
+ CallRequest,
22
+ Detector,
23
+ Halt,
24
+ LedgerView,
25
+ Observation,
26
+ Policy,
27
+ Severity,
28
+ Signal,
29
+ Usage,
30
+ )
31
+ from tokenops.control.config import build_governor, build_governance_stack
32
+ from tokenops.control.engine import (
33
+ AgentControls,
34
+ ApplyControls,
35
+ Governor,
36
+ PreviewControls,
37
+ RaiseControls,
38
+ Throttled,
39
+ governance_events_payload,
40
+ halt_detector_from_events,
41
+ )
42
+ from tokenops.control.integration import (
43
+ apply_carry_to_messages,
44
+ consume_carry,
45
+ make_on_step,
46
+ step_to_observation,
47
+ wrap_complete,
48
+ wrap_stream,
49
+ )
50
+ from tokenops.control.ledger import Budget, Ledger, RunState, segment_key
51
+ from tokenops.control.attribution import (
52
+ begin_downstream_run,
53
+ begin_entry_run,
54
+ begin_entry_task_run,
55
+ build_attribution,
56
+ downstream_run_scope,
57
+ entry_run_scope,
58
+ entry_task_run_scope,
59
+ require_registration,
60
+ )
61
+ from tokenops.control.context import (
62
+ PARENT_SPAN_ID_HEADER,
63
+ RUN_ID_HEADER,
64
+ GovernanceContext,
65
+ SpanContext,
66
+ governance_scope,
67
+ )
68
+ from tokenops.control.boundary import emit_observation, observation_from_crossing
69
+ from tokenops.control.crossing import install_crossing_hook, on_crossing
70
+
71
+ # Process-wide: re-attach after every reset_session (Chronicle clears on_crossing).
72
+ install_crossing_hook()
73
+
74
+ from tokenops.control.http import (
75
+ mount_run_registration,
76
+ post_run,
77
+ post_run_sync,
78
+ with_governance_errors,
79
+ )
80
+ from tokenops.control.client import ControlPlaneClient, should_mount_run_registration
81
+ from tokenops.control.models import GovernanceMode, RunRegistration, parse_governance_mode
82
+ from tokenops.control.propagate import merge_propagation_headers, propagation_headers
83
+
84
+ __all__ = [
85
+ # vocabulary
86
+ "Action", "ActionKind", "Attribution", "BoundaryStep", "CallRequest",
87
+ "Detector", "Halt", "LedgerView", "Observation", "Policy", "Severity",
88
+ "Signal", "Usage",
89
+ # ledger
90
+ "Budget", "Ledger", "RunState", "segment_key",
91
+ # harness
92
+ "Governor", "RaiseControls", "AgentControls", "ApplyControls", "PreviewControls", "Throttled",
93
+ # config factory
94
+ "build_governor", "build_governance_stack",
95
+ # data-plane integration
96
+ "make_on_step", "wrap_complete", "wrap_stream", "apply_carry_to_messages", "consume_carry",
97
+ "step_to_observation",
98
+ # attribution
99
+ "RunRegistration", "GovernanceMode", "parse_governance_mode", "build_attribution", "begin_entry_run", "begin_downstream_run",
100
+ "begin_entry_task_run",
101
+ "require_registration", "entry_run_scope", "entry_task_run_scope", "downstream_run_scope",
102
+ "RUN_ID_HEADER", "PARENT_SPAN_ID_HEADER", "SpanContext", "GovernanceContext",
103
+ "governance_scope", "observation_from_crossing", "emit_observation",
104
+ # Chronicle crossing hook
105
+ "install_crossing_hook", "on_crossing",
106
+ # HTTP (A2A mount + clients)
107
+ "mount_run_registration", "with_governance_errors", "post_run", "post_run_sync",
108
+ "ControlPlaneClient", "should_mount_run_registration",
109
+ # HTTP propagation (auto run_id / parent span)
110
+ "propagation_headers", "merge_propagation_headers",
111
+ ]