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.
- agent_tokenops-0.1.0.dist-info/METADATA +305 -0
- agent_tokenops-0.1.0.dist-info/RECORD +63 -0
- agent_tokenops-0.1.0.dist-info/WHEEL +5 -0
- agent_tokenops-0.1.0.dist-info/licenses/LICENSE.txt +21 -0
- agent_tokenops-0.1.0.dist-info/top_level.txt +1 -0
- tokenops/__init__.py +12 -0
- tokenops/config/__init__.py +3 -0
- tokenops/config/default.yaml +37 -0
- tokenops/config/loader.py +30 -0
- tokenops/control/__init__.py +111 -0
- tokenops/control/attribution.py +185 -0
- tokenops/control/boundary.py +145 -0
- tokenops/control/client.py +146 -0
- tokenops/control/config.py +162 -0
- tokenops/control/context.py +136 -0
- tokenops/control/core.py +329 -0
- tokenops/control/crossing.py +99 -0
- tokenops/control/engine.py +293 -0
- tokenops/control/http.py +126 -0
- tokenops/control/integration.py +375 -0
- tokenops/control/ledger.py +297 -0
- tokenops/control/models.py +117 -0
- tokenops/control/policies/__init__.py +33 -0
- tokenops/control/policies/_util.py +89 -0
- tokenops/control/policies/concurrency_cap.py +80 -0
- tokenops/control/policies/context_compaction.py +78 -0
- tokenops/control/policies/cost_budget.py +68 -0
- tokenops/control/policies/cost_guard.py +98 -0
- tokenops/control/policies/output_runaway.py +94 -0
- tokenops/control/policies/pre_call_worst_case.py +103 -0
- tokenops/control/policies/progress_guard.py +105 -0
- tokenops/control/policies/step_cap.py +57 -0
- tokenops/control/policies/tool_fix.py +100 -0
- tokenops/control/policies/tool_output_cap.py +88 -0
- tokenops/control/policies/trajectory_hint.py +254 -0
- tokenops/control/pricing.py +68 -0
- tokenops/control/propagate.py +46 -0
- tokenops/control/store.py +717 -0
- tokenops/control/trajectory/__init__.py +15 -0
- tokenops/control/trajectory/compress.py +43 -0
- tokenops/control/trajectory/enqueue.py +64 -0
- tokenops/control/trajectory/gates.py +35 -0
- tokenops/control/trajectory/hint.py +75 -0
- tokenops/control/trajectory/scope.py +69 -0
- tokenops/control/trajectory/serialize.py +66 -0
- tokenops/control/trajectory/worker.py +29 -0
- tokenops/env.py +22 -0
- tokenops/providers/__init__.py +4 -0
- tokenops/providers/anthropic.py +28 -0
- tokenops/providers/factory.py +39 -0
- tokenops/providers/openai.py +54 -0
- tokenops/providers/types.py +10 -0
- tokenops/server/__init__.py +5 -0
- tokenops/server/__main__.py +26 -0
- tokenops/server/app.py +38 -0
- tokenops/ui/__init__.py +0 -0
- tokenops/ui/app.py +28 -0
- tokenops/ui/run_detail.py +120 -0
- tokenops/ui/store_client.py +25 -0
- tokenops/ui/theme.py +145 -0
- tokenops/ui/views/__init__.py +0 -0
- tokenops/ui/views/admin.py +260 -0
- 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
|
+
[](https://github.com/theagentplane/tokenops/actions/workflows/test.yml)
|
|
51
|
+
[](https://pypi.org/project/agent-tokenops/)
|
|
52
|
+
[](https://github.com/theagentplane/tokenops)
|
|
53
|
+
[](LICENSE.txt)
|
|
54
|
+
[](https://semver.org/)
|
|
55
|
+
[](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
|
+
[](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,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,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
|
+
]
|