tokenjam 0.2.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 (202) hide show
  1. tokenjam-0.2.0/.github/CODEOWNERS +2 -0
  2. tokenjam-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  3. tokenjam-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +16 -0
  4. tokenjam-0.2.0/.github/ISSUE_TEMPLATE/integration_request.md +21 -0
  5. tokenjam-0.2.0/.github/pull_request_template.md +11 -0
  6. tokenjam-0.2.0/.github/workflows/ci.yml +48 -0
  7. tokenjam-0.2.0/.github/workflows/publish-npm.yml +35 -0
  8. tokenjam-0.2.0/.github/workflows/publish-pypi.yml +31 -0
  9. tokenjam-0.2.0/.gitignore +52 -0
  10. tokenjam-0.2.0/.tj/config.toml +27 -0
  11. tokenjam-0.2.0/AGENTS.md +17 -0
  12. tokenjam-0.2.0/CHANGELOG.md +150 -0
  13. tokenjam-0.2.0/CLAUDE.md +232 -0
  14. tokenjam-0.2.0/CONTRIBUTING.md +70 -0
  15. tokenjam-0.2.0/LICENSE +21 -0
  16. tokenjam-0.2.0/Makefile +18 -0
  17. tokenjam-0.2.0/PKG-INFO +622 -0
  18. tokenjam-0.2.0/README.md +566 -0
  19. tokenjam-0.2.0/SECURITY.md +29 -0
  20. tokenjam-0.2.0/docs/alerts.md +116 -0
  21. tokenjam-0.2.0/docs/architecture.md +419 -0
  22. tokenjam-0.2.0/docs/claude-code-integration.md +81 -0
  23. tokenjam-0.2.0/docs/cli-reference.md +164 -0
  24. tokenjam-0.2.0/docs/configuration.md +112 -0
  25. tokenjam-0.2.0/docs/export.md +75 -0
  26. tokenjam-0.2.0/docs/framework-support.md +72 -0
  27. tokenjam-0.2.0/docs/nemoclaw-integration.md +48 -0
  28. tokenjam-0.2.0/docs/openclaw.md +102 -0
  29. tokenjam-0.2.0/examples/README.md +106 -0
  30. tokenjam-0.2.0/examples/alerts_and_drift/_shared.py +55 -0
  31. tokenjam-0.2.0/examples/alerts_and_drift/budget_breach_demo.py +111 -0
  32. tokenjam-0.2.0/examples/alerts_and_drift/drift_demo.py +130 -0
  33. tokenjam-0.2.0/examples/alerts_and_drift/sensitive_actions_demo.py +155 -0
  34. tokenjam-0.2.0/examples/multi/rag_pipeline.py +164 -0
  35. tokenjam-0.2.0/examples/multi/research_team.py +189 -0
  36. tokenjam-0.2.0/examples/multi/router_agent.py +149 -0
  37. tokenjam-0.2.0/examples/multi/sample_docs/agent_patterns.txt +21 -0
  38. tokenjam-0.2.0/examples/multi/sample_docs/cost_management.txt +23 -0
  39. tokenjam-0.2.0/examples/multi/sample_docs/observability.txt +21 -0
  40. tokenjam-0.2.0/examples/multi/sample_docs/safety.txt +24 -0
  41. tokenjam-0.2.0/examples/openclaw/README.md +103 -0
  42. tokenjam-0.2.0/examples/single_framework/autogen_agent.py +85 -0
  43. tokenjam-0.2.0/examples/single_framework/crewai_agent.py +89 -0
  44. tokenjam-0.2.0/examples/single_framework/langchain_agent.py +104 -0
  45. tokenjam-0.2.0/examples/single_framework/langgraph_agent.py +116 -0
  46. tokenjam-0.2.0/examples/single_framework/llamaindex_agent.py +116 -0
  47. tokenjam-0.2.0/examples/single_provider/anthropic_agent.py +188 -0
  48. tokenjam-0.2.0/examples/single_provider/bedrock_agent.py +102 -0
  49. tokenjam-0.2.0/examples/single_provider/gemini_agent.py +107 -0
  50. tokenjam-0.2.0/examples/single_provider/litellm_agent.py +92 -0
  51. tokenjam-0.2.0/examples/single_provider/openai_agent.py +178 -0
  52. tokenjam-0.2.0/examples/single_provider/openai_agents_sdk_agent.py +127 -0
  53. tokenjam-0.2.0/incidents/hallucination-drift/BLOG.md +82 -0
  54. tokenjam-0.2.0/incidents/hallucination-drift/README.md +78 -0
  55. tokenjam-0.2.0/incidents/hallucination-drift/scenario.py +177 -0
  56. tokenjam-0.2.0/incidents/retry-loop/BLOG.md +86 -0
  57. tokenjam-0.2.0/incidents/retry-loop/README.md +75 -0
  58. tokenjam-0.2.0/incidents/retry-loop/scenario.py +134 -0
  59. tokenjam-0.2.0/incidents/surprise-cost/BLOG.md +96 -0
  60. tokenjam-0.2.0/incidents/surprise-cost/README.md +93 -0
  61. tokenjam-0.2.0/incidents/surprise-cost/scenario.py +155 -0
  62. tokenjam-0.2.0/pricing/models.toml +70 -0
  63. tokenjam-0.2.0/pyproject.toml +81 -0
  64. tokenjam-0.2.0/sdk-ts/README.md +178 -0
  65. tokenjam-0.2.0/sdk-ts/package-lock.json +51 -0
  66. tokenjam-0.2.0/sdk-ts/package.json +32 -0
  67. tokenjam-0.2.0/sdk-ts/src/client.test.ts +248 -0
  68. tokenjam-0.2.0/sdk-ts/src/client.ts +233 -0
  69. tokenjam-0.2.0/sdk-ts/src/index.ts +4 -0
  70. tokenjam-0.2.0/sdk-ts/src/semconv.test.ts +29 -0
  71. tokenjam-0.2.0/sdk-ts/src/semconv.ts +82 -0
  72. tokenjam-0.2.0/sdk-ts/src/span-builder.test.ts +117 -0
  73. tokenjam-0.2.0/sdk-ts/src/span-builder.ts +157 -0
  74. tokenjam-0.2.0/sdk-ts/src/types.ts +76 -0
  75. tokenjam-0.2.0/sdk-ts/tsconfig.json +19 -0
  76. tokenjam-0.2.0/tests/__init__.py +0 -0
  77. tokenjam-0.2.0/tests/agents/__init__.py +0 -0
  78. tokenjam-0.2.0/tests/agents/email_agent_budget_breach.py +15 -0
  79. tokenjam-0.2.0/tests/agents/email_agent_drift.py +14 -0
  80. tokenjam-0.2.0/tests/agents/email_agent_loop.py +16 -0
  81. tokenjam-0.2.0/tests/agents/email_agent_normal.py +20 -0
  82. tokenjam-0.2.0/tests/agents/mock_llm.py +40 -0
  83. tokenjam-0.2.0/tests/agents/test_mock_scenarios.py +228 -0
  84. tokenjam-0.2.0/tests/conftest.py +6 -0
  85. tokenjam-0.2.0/tests/e2e/__init__.py +0 -0
  86. tokenjam-0.2.0/tests/e2e/conftest.py +12 -0
  87. tokenjam-0.2.0/tests/e2e/test_real_llm.py +168 -0
  88. tokenjam-0.2.0/tests/factories.py +281 -0
  89. tokenjam-0.2.0/tests/integration/__init__.py +0 -0
  90. tokenjam-0.2.0/tests/integration/test_api.py +364 -0
  91. tokenjam-0.2.0/tests/integration/test_cli.py +595 -0
  92. tokenjam-0.2.0/tests/integration/test_db.py +399 -0
  93. tokenjam-0.2.0/tests/integration/test_demos.py +87 -0
  94. tokenjam-0.2.0/tests/integration/test_full_pipeline.py +321 -0
  95. tokenjam-0.2.0/tests/integration/test_logs_api.py +235 -0
  96. tokenjam-0.2.0/tests/manual-new-release-tests.md +158 -0
  97. tokenjam-0.2.0/tests/manual-pre-release-testing.md +279 -0
  98. tokenjam-0.2.0/tests/synthetic/__init__.py +0 -0
  99. tokenjam-0.2.0/tests/synthetic/test_alert_rules.py +429 -0
  100. tokenjam-0.2.0/tests/synthetic/test_cost_tracking.py +140 -0
  101. tokenjam-0.2.0/tests/synthetic/test_drift_detection.py +295 -0
  102. tokenjam-0.2.0/tests/synthetic/test_ingest.py +351 -0
  103. tokenjam-0.2.0/tests/synthetic/test_schema_validation.py +291 -0
  104. tokenjam-0.2.0/tests/toy_agent/toy_agent.py +20 -0
  105. tokenjam-0.2.0/tests/unit/__init__.py +0 -0
  106. tokenjam-0.2.0/tests/unit/test_alerts.py +52 -0
  107. tokenjam-0.2.0/tests/unit/test_cmd_stop.py +68 -0
  108. tokenjam-0.2.0/tests/unit/test_config.py +289 -0
  109. tokenjam-0.2.0/tests/unit/test_cost.py +116 -0
  110. tokenjam-0.2.0/tests/unit/test_demo_env.py +69 -0
  111. tokenjam-0.2.0/tests/unit/test_demo_scenarios.py +56 -0
  112. tokenjam-0.2.0/tests/unit/test_drift.py +78 -0
  113. tokenjam-0.2.0/tests/unit/test_formatting.py +56 -0
  114. tokenjam-0.2.0/tests/unit/test_litellm_integration.py +290 -0
  115. tokenjam-0.2.0/tests/unit/test_logs_converter.py +513 -0
  116. tokenjam-0.2.0/tests/unit/test_mcp_server.py +644 -0
  117. tokenjam-0.2.0/tests/unit/test_models.py +111 -0
  118. tokenjam-0.2.0/tests/unit/test_onboard_codex.py +34 -0
  119. tokenjam-0.2.0/tests/unit/test_onboard_daemon.py +88 -0
  120. tokenjam-0.2.0/tests/unit/test_openclaw_ingest.py +355 -0
  121. tokenjam-0.2.0/tests/unit/test_time_parse.py +97 -0
  122. tokenjam-0.2.0/tokenjam/__init__.py +1 -0
  123. tokenjam-0.2.0/tokenjam/api/__init__.py +0 -0
  124. tokenjam-0.2.0/tokenjam/api/app.py +104 -0
  125. tokenjam-0.2.0/tokenjam/api/deps.py +18 -0
  126. tokenjam-0.2.0/tokenjam/api/middleware.py +28 -0
  127. tokenjam-0.2.0/tokenjam/api/routes/__init__.py +0 -0
  128. tokenjam-0.2.0/tokenjam/api/routes/agents.py +33 -0
  129. tokenjam-0.2.0/tokenjam/api/routes/alerts.py +77 -0
  130. tokenjam-0.2.0/tokenjam/api/routes/budget.py +96 -0
  131. tokenjam-0.2.0/tokenjam/api/routes/cost.py +43 -0
  132. tokenjam-0.2.0/tokenjam/api/routes/drift.py +63 -0
  133. tokenjam-0.2.0/tokenjam/api/routes/logs.py +511 -0
  134. tokenjam-0.2.0/tokenjam/api/routes/metrics.py +81 -0
  135. tokenjam-0.2.0/tokenjam/api/routes/otlp.py +63 -0
  136. tokenjam-0.2.0/tokenjam/api/routes/spans.py +202 -0
  137. tokenjam-0.2.0/tokenjam/api/routes/status.py +84 -0
  138. tokenjam-0.2.0/tokenjam/api/routes/tools.py +22 -0
  139. tokenjam-0.2.0/tokenjam/api/routes/traces.py +92 -0
  140. tokenjam-0.2.0/tokenjam/cli/__init__.py +0 -0
  141. tokenjam-0.2.0/tokenjam/cli/cmd_alerts.py +94 -0
  142. tokenjam-0.2.0/tokenjam/cli/cmd_budget.py +119 -0
  143. tokenjam-0.2.0/tokenjam/cli/cmd_cost.py +90 -0
  144. tokenjam-0.2.0/tokenjam/cli/cmd_demo.py +82 -0
  145. tokenjam-0.2.0/tokenjam/cli/cmd_doctor.py +173 -0
  146. tokenjam-0.2.0/tokenjam/cli/cmd_drift.py +238 -0
  147. tokenjam-0.2.0/tokenjam/cli/cmd_export.py +200 -0
  148. tokenjam-0.2.0/tokenjam/cli/cmd_mcp.py +78 -0
  149. tokenjam-0.2.0/tokenjam/cli/cmd_onboard.py +779 -0
  150. tokenjam-0.2.0/tokenjam/cli/cmd_serve.py +85 -0
  151. tokenjam-0.2.0/tokenjam/cli/cmd_status.py +153 -0
  152. tokenjam-0.2.0/tokenjam/cli/cmd_stop.py +87 -0
  153. tokenjam-0.2.0/tokenjam/cli/cmd_tools.py +45 -0
  154. tokenjam-0.2.0/tokenjam/cli/cmd_traces.py +161 -0
  155. tokenjam-0.2.0/tokenjam/cli/cmd_uninstall.py +159 -0
  156. tokenjam-0.2.0/tokenjam/cli/main.py +110 -0
  157. tokenjam-0.2.0/tokenjam/core/__init__.py +0 -0
  158. tokenjam-0.2.0/tokenjam/core/alerts.py +619 -0
  159. tokenjam-0.2.0/tokenjam/core/api_backend.py +235 -0
  160. tokenjam-0.2.0/tokenjam/core/config.py +360 -0
  161. tokenjam-0.2.0/tokenjam/core/cost.py +102 -0
  162. tokenjam-0.2.0/tokenjam/core/db.py +718 -0
  163. tokenjam-0.2.0/tokenjam/core/drift.py +256 -0
  164. tokenjam-0.2.0/tokenjam/core/ingest.py +265 -0
  165. tokenjam-0.2.0/tokenjam/core/models.py +225 -0
  166. tokenjam-0.2.0/tokenjam/core/pricing.py +54 -0
  167. tokenjam-0.2.0/tokenjam/core/retention.py +21 -0
  168. tokenjam-0.2.0/tokenjam/core/schema_validator.py +156 -0
  169. tokenjam-0.2.0/tokenjam/demo/__init__.py +0 -0
  170. tokenjam-0.2.0/tokenjam/demo/env.py +96 -0
  171. tokenjam-0.2.0/tokenjam/mcp/__init__.py +0 -0
  172. tokenjam-0.2.0/tokenjam/mcp/server.py +1067 -0
  173. tokenjam-0.2.0/tokenjam/otel/__init__.py +0 -0
  174. tokenjam-0.2.0/tokenjam/otel/exporters.py +26 -0
  175. tokenjam-0.2.0/tokenjam/otel/provider.py +207 -0
  176. tokenjam-0.2.0/tokenjam/otel/semconv.py +144 -0
  177. tokenjam-0.2.0/tokenjam/pricing/models.toml +70 -0
  178. tokenjam-0.2.0/tokenjam/py.typed +0 -0
  179. tokenjam-0.2.0/tokenjam/sdk/__init__.py +21 -0
  180. tokenjam-0.2.0/tokenjam/sdk/agent.py +206 -0
  181. tokenjam-0.2.0/tokenjam/sdk/bootstrap.py +120 -0
  182. tokenjam-0.2.0/tokenjam/sdk/http_exporter.py +109 -0
  183. tokenjam-0.2.0/tokenjam/sdk/integrations/__init__.py +0 -0
  184. tokenjam-0.2.0/tokenjam/sdk/integrations/anthropic.py +200 -0
  185. tokenjam-0.2.0/tokenjam/sdk/integrations/autogen.py +97 -0
  186. tokenjam-0.2.0/tokenjam/sdk/integrations/base.py +27 -0
  187. tokenjam-0.2.0/tokenjam/sdk/integrations/bedrock.py +103 -0
  188. tokenjam-0.2.0/tokenjam/sdk/integrations/crewai.py +96 -0
  189. tokenjam-0.2.0/tokenjam/sdk/integrations/gemini.py +131 -0
  190. tokenjam-0.2.0/tokenjam/sdk/integrations/langchain.py +156 -0
  191. tokenjam-0.2.0/tokenjam/sdk/integrations/langgraph.py +101 -0
  192. tokenjam-0.2.0/tokenjam/sdk/integrations/litellm.py +323 -0
  193. tokenjam-0.2.0/tokenjam/sdk/integrations/llamaindex.py +52 -0
  194. tokenjam-0.2.0/tokenjam/sdk/integrations/nemoclaw.py +139 -0
  195. tokenjam-0.2.0/tokenjam/sdk/integrations/openai.py +159 -0
  196. tokenjam-0.2.0/tokenjam/sdk/integrations/openai_agents_sdk.py +47 -0
  197. tokenjam-0.2.0/tokenjam/sdk/transport.py +98 -0
  198. tokenjam-0.2.0/tokenjam/ui/index.html +1213 -0
  199. tokenjam-0.2.0/tokenjam/utils/__init__.py +0 -0
  200. tokenjam-0.2.0/tokenjam/utils/formatting.py +43 -0
  201. tokenjam-0.2.0/tokenjam/utils/ids.py +15 -0
  202. tokenjam-0.2.0/tokenjam/utils/time_parse.py +54 -0
@@ -0,0 +1,2 @@
1
+ # Global owner — all files require review from @anilmurty
2
+ * @anilmurty
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a bug in TokenJam
4
+ title: ''
5
+ labels: bug
6
+ assignees: ''
7
+ ---
8
+
9
+ **Describe the bug**
10
+ A clear description of what went wrong.
11
+
12
+ **To reproduce**
13
+ ```bash
14
+ # The command you ran
15
+ ```
16
+
17
+ **Expected behavior**
18
+ What you expected to happen.
19
+
20
+ **Error output**
21
+ ```
22
+ # Full error output
23
+ ```
24
+
25
+ **Environment**
26
+ - OS:
27
+ - Python version (`python3 --version`):
28
+ - tj version (`pip show tokenjam`):
29
+ - Output of `tj doctor` (if relevant):
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest a feature or improvement
4
+ title: ''
5
+ labels: enhancement
6
+ assignees: ''
7
+ ---
8
+
9
+ **What problem does this solve?**
10
+ A clear description of the problem or use case.
11
+
12
+ **Proposed solution**
13
+ How you think it should work.
14
+
15
+ **Alternatives considered**
16
+ Any other approaches you considered.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: Integration request
3
+ about: Request a new framework or provider integration
4
+ title: 'Integration: '
5
+ labels: integration
6
+ assignees: ''
7
+ ---
8
+
9
+ **Framework / Provider**
10
+ Name and link to the project.
11
+
12
+ **How it handles telemetry today**
13
+ Does it have built-in OTel support? What spans/events does it emit?
14
+
15
+ **Proposed approach**
16
+ - [ ] Provider patch (monkey-patch API calls)
17
+ - [ ] Framework patch (wrap LLM/tool abstractions)
18
+ - [ ] OTLP bridge (thin wrapper around built-in OTel support)
19
+
20
+ **Are you willing to implement this?**
21
+ Yes / No — if yes, please read `tokenjam/sdk/integrations/anthropic.py` as the reference implementation before starting.
@@ -0,0 +1,11 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do? 1-3 sentences. -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] Tests pass (`pytest tests/unit/ tests/synthetic/ tests/agents/ tests/integration/`)
8
+ - [ ] Lint clean (`ruff check tokenjam/`)
9
+ - [ ] Type check clean (`mypy tokenjam/`)
10
+ - [ ] CLAUDE.md updated (if architecture changed)
11
+ - [ ] Test spans use `tests/factories.py` (not raw `NormalizedSpan`)
@@ -0,0 +1,48 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev,mcp]"
26
+
27
+ - name: Lint
28
+ run: ruff check tokenjam/
29
+
30
+ - name: Type check
31
+ run: mypy tokenjam/
32
+
33
+ - name: Run tests
34
+ run: pytest tests/unit/ tests/synthetic/ tests/agents/ tests/integration/
35
+
36
+ test-ts:
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+
41
+ - name: Set up Node
42
+ uses: actions/setup-node@v4
43
+ with:
44
+ node-version: "22"
45
+
46
+ - name: Install and test TypeScript SDK
47
+ working-directory: sdk-ts
48
+ run: npm install && npm test
@@ -0,0 +1,35 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish-npm:
9
+ if: startsWith(github.ref_name, 'v')
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version: "22"
17
+ registry-url: https://registry.npmjs.org
18
+
19
+ - name: Install dependencies
20
+ working-directory: sdk-ts
21
+ run: npm install
22
+
23
+ - name: Run tests
24
+ working-directory: sdk-ts
25
+ run: npm test
26
+
27
+ - name: Build
28
+ working-directory: sdk-ts
29
+ run: npm run build
30
+
31
+ - name: Publish
32
+ working-directory: sdk-ts
33
+ run: npm publish --access public
34
+ env:
35
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,31 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish-pypi:
9
+ if: startsWith(github.ref_name, 'v')
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ environment: pypi
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install dependencies
22
+ run: pip install build ".[dev,mcp]"
23
+
24
+ - name: Run tests
25
+ run: pytest tests/unit/ tests/synthetic/ tests/agents/ tests/integration/ -x
26
+
27
+ - name: Build package
28
+ run: python -m build
29
+
30
+ - name: Publish to PyPI
31
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,52 @@
1
+ # Python
2
+ **/__pycache__/
3
+ **/*.pyc
4
+ **/*.pyo
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ *.egg
9
+
10
+ # Virtual environments
11
+ .venv/
12
+ venv/
13
+
14
+ # DuckDB
15
+ *.duckdb
16
+ *.duckdb.wal
17
+
18
+ # IDE
19
+ .idea/
20
+ .vscode/
21
+ *.swp
22
+ *.swo
23
+
24
+ # OS
25
+ .DS_Store
26
+ Thumbs.db
27
+
28
+ # Test / lint caches
29
+ .pytest_cache/
30
+ .ruff_cache/
31
+ .mypy_cache/
32
+ htmlcov/
33
+ .coverage
34
+
35
+ # Node (sdk-ts)
36
+ sdk-ts/node_modules/
37
+ sdk-ts/dist/
38
+
39
+ # Secrets and env files
40
+ .env
41
+ .env.*
42
+ ocw.toml
43
+ .ocw/
44
+
45
+ # Claude Code
46
+ .claude/
47
+ .omc/
48
+ .mcp.json
49
+
50
+ # Superpowers skill output (internal planning artifacts, not for OSS)
51
+ docs/superpowers/
52
+ .gstack/
@@ -0,0 +1,27 @@
1
+ # TokenJam configuration
2
+ # Docs: https://github.com/Metabuilder-Labs/openclawwatch#configuration
3
+
4
+ [defaults.budget]
5
+ daily_usd = 5.0
6
+
7
+ [security]
8
+ ingest_secret = "77755a66f3beea005867bafe9183663e7420435d3bff69c4453f4cadab103fc6"
9
+
10
+ [capture]
11
+ prompts = false
12
+ completions = false
13
+ tool_outputs = false
14
+
15
+ [storage]
16
+ path = "~/.tj/telemetry.duckdb"
17
+ retention_days = 90
18
+
19
+ # Per-agent overrides (optional):
20
+ # [agents.my-agent]
21
+ # description = "My email agent"
22
+ # [agents.my-agent.budget]
23
+ # daily_usd = 5.00
24
+ # session_usd = 1.00
25
+ # [[agents.my-agent.sensitive_actions]]
26
+ # name = "send_email"
27
+ # severity = "critical"
@@ -0,0 +1,17 @@
1
+ # AGENTS.md — TokenJam
2
+
3
+ > **AI coding agents working in this repo should read [`CLAUDE.md`](./CLAUDE.md) instead.**
4
+ > CLAUDE.md is the maintained source of truth and is kept up to date by the agents
5
+ > working in this codebase. This file exists only for tools that look specifically
6
+ > for AGENTS.md (Codex, Gemini Code, etc.).
7
+
8
+ ## Quick rules for agents that don't read CLAUDE.md
9
+
10
+ 1. Storage is **DuckDB** — never `import sqlite3`, never write SQLite queries
11
+ 2. Config is **TOML** — `tomllib.load()` requires `open(path, "rb")` binary mode
12
+ 3. `tokenjam/core/` has **no CLI or HTTP imports** — pure domain logic only
13
+ 4. `@watch()` alone does **not** create LLM spans — requires `patch_anthropic()` etc.
14
+ 5. Never use unicode bullet characters in output — Rich handles formatting
15
+ 6. Tests use `InMemoryBackend` and `tests/factories.py` — never construct `NormalizedSpan` directly
16
+
17
+ **Read [CLAUDE.md](./CLAUDE.md) for the full architecture, development guide, and current rules.**
@@ -0,0 +1,150 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [0.1.7] - 2026-04-13
9
+
10
+ ### Added
11
+ - **MCP server (`tj mcp`)** — stdio-based Model Context Protocol server giving Claude Code direct access to OCW observability data. 13 tool handlers: status, traces, alerts, budget headroom, cost summary, drift report, tool stats, trace detail, acknowledge alerts, setup project, list sessions, open dashboard. Dual-mode operation: routes queries through REST API when `tj serve` is running, falls back to read-only DuckDB otherwise. Auto-starts `tj serve` on demand.
12
+ - **Claude Code integration (`tj onboard --claude-code`)** — one-command setup for Claude Code telemetry. Configures OTLP log exporter in `~/.claude/settings.json`, sets project-level `OTEL_RESOURCE_ATTRIBUTES`, adds Docker-compatible endpoint to shell env, and optionally installs background daemon. Re-runs resync the auth header to fix 401s without manual setup.
13
+ - **Logs ingestion (`POST /v1/logs`)** — new OTLP log endpoint that converts Claude Code log events (`api_request`, `tool_result`, `api_error`, `user_prompt`, `tool_decision`) into NormalizedSpans with deterministic trace/span IDs. Spans flow through the standard ingest pipeline for cost, alerts, and drift.
14
+ - **`tj drift` CLI** — behavioral drift report with Rich table output showing baseline vs latest session Z-scores per dimension (input tokens, output tokens, duration, tool call count, tool sequence similarity). Color-coded thresholds, `--json` support, exit code 1 if drift detected.
15
+ - **`tj budget` CLI + API** — view and set per-agent daily/session cost limits. `GET/POST /api/v1/budget` endpoints. `resolve_effective_budget()` with per-field fallback so each budget dimension independently falls back to defaults.
16
+ - **Architecture documentation** (`docs/architecture.md`) — comprehensive architecture doc covering design principles, data flow, SDK internals, alert system, drift detection, MCP server, Claude Code pipeline, and testing architecture.
17
+ - `ClaudeCodeEvents` semantic conventions in `tokenjam/otel/semconv.py` for Claude Code log event attributes
18
+
19
+ ### Fixed
20
+ - Budget resolution inconsistency between AlertEngine enforcement and CLI display — both now use `resolve_effective_budget()` with field-level merge
21
+ - Drift display threshold bug in Z-score comparison
22
+ - `tj stop` now passes `-w` to `launchctl unload` to prevent auto-restart on macOS; added Linux systemd support
23
+ - Waterfall tooltip clipping for right-edge spans in web UI
24
+ - CLAUDE.md install command corrected from `pip install tokenjam` to `pip install tokenjam`
25
+
26
+ ### Improved
27
+ - README updated with Claude Code integration section, budget/drift CLI references, MCP server docs
28
+ - Web UI: budget headroom display, cost-today column in active sessions table, tooltip polish
29
+ - Onboard wizard: expanded for Claude Code workflow, status command enhancements
30
+ - MCP tool descriptions optimized for better agent tool selection
31
+
32
+ ### Changed
33
+ - Removed historical task specs from `.claude/specs/` (design intent preserved in `docs/architecture.md`)
34
+ - CLAUDE.md "Task Specs" section replaced with "Further Reading" linking to architecture doc
35
+ - 338 tests passing (up from 223)
36
+
37
+ ## [0.1.6] - 2026-04-08
38
+
39
+ ### Improved
40
+ - **`tj onboard` UX overhaul**
41
+ - Removed agent ID prompt — agents are auto-discovered when spans arrive
42
+ - Budget is now a global default (`[defaults.budget]`) that applies to all agents
43
+ - Per-agent `[agents.X.budget]` overrides the default when configured
44
+ - Cleaner budget prompt: "Daily budget in USD per agent (0 = no limit, default 5)"
45
+ - Daemon installs automatically (skip with `--no-daemon`)
46
+ - Rich next-steps output with instrumentation code example
47
+ - Minimal config file with commented per-agent example
48
+
49
+ ## [0.1.5] - 2026-04-08
50
+
51
+ ### Fixed
52
+ - **Pricing file missing from pip wheel** — `pricing/models.toml` was at the repo root, outside the `tokenjam/` package. Moved to `tokenjam/pricing/models.toml` so it's included in the wheel. All costs showed `$0.000000` in v0.1.4.
53
+
54
+ ### Improved
55
+ - **Web UI polish** — custom hover tooltips on waterfall bars (cost, duration, model), back arrow on trace detail, agent name heading, tighter layout, hint text on Status and Traces views
56
+ - **Waterfall bar labels** — now show cost alongside duration and model name
57
+
58
+ ### Added
59
+ - Manual release testing checklist (`tests/manual-new-release-tests.md`)
60
+ - Pre-release testing checklist (`tests/manual-pre-release-testing.md`)
61
+
62
+ ### Changed
63
+ - Task specs moved from `.claude/` to `.claude/specs/`
64
+
65
+ ## [0.1.4] - 2026-04-08
66
+
67
+ ### Fixed
68
+ - SDK DuckDB lock error when `tj serve` is running — bootstrap now detects the server and sends spans via HTTP (`TjHttpExporter`) instead of opening DuckDB directly
69
+ - LiteLLM model names no longer include provider prefix (`gpt-4o-mini` not `openai/gpt-4o-mini`), fixing pricing lookup failures
70
+ - LiteLLM streaming wrappers now correctly attribute provider and stripped model name
71
+
72
+ ### Added
73
+ - OpenClaw integration — zero-code OTLP ingestion for OpenClaw agents (PR #15)
74
+ - Web UI restyled to opencla.watch palette (deep navy + electric blue, IBM Plex Mono, Bricolage Grotesque)
75
+ - Inline SVG logo in web UI sidebar
76
+
77
+ ### Changed
78
+ - Node.js upgraded from 20 to 22 in CI and publish workflows
79
+ - npm SDK bumped to 0.1.4 (matching Python release)
80
+ - README: added Web UI section, updated roadmap (4 items complete, 5 new)
81
+
82
+ ## [0.1.3] - 2026-04-07
83
+
84
+ ### Added
85
+ - **Web UI** — local dashboard served by `tj serve` at `http://127.0.0.1:7391/`
86
+ - Status view with agent cards, cost, tokens, alerts (auto-refresh 5s)
87
+ - Traces view with span waterfall visualization and click-to-inspect detail
88
+ - Cost view with breakdown by day/agent/model/tool and summary totals
89
+ - Alerts view with severity filtering and expandable JSON detail
90
+ - Drift view with baseline vs latest session Z-score pass/fail
91
+ - `GET /api/v1/status` endpoint — agent status data (mirrors `tj status --json`)
92
+ - Drift endpoint now lists all agents when `agent_id` is omitted
93
+ - LiteLLM provider integration (`patch_litellm()`)
94
+ - Single-file Preact SPA — no build step, dark theme, JetBrains Mono
95
+
96
+ ### Changed
97
+ - CORS updated to regex matching for `localhost:*` ports
98
+ - API key injected into UI via `<meta>` tag (no user prompt needed)
99
+
100
+ ## [0.1.2] - 2026-04-07
101
+
102
+ ### Fixed
103
+ - `tj serve` printing wrong metrics port (9464 instead of 7391)
104
+ - `tj onboard` launchd daemon install now degrades gracefully on failure instead of crashing
105
+ - CLI commands now fall back to REST API when DuckDB is locked by `tj serve`
106
+
107
+ ### Added
108
+ - `tj stop` command — graceful shutdown of daemon or background process
109
+ - `tj uninstall` command — clean removal of all OCW data, config, and daemon
110
+ - 16 runnable example agents across 4 tiers: single provider, single framework, multi-agent, and alerts/drift demos
111
+ - API fallback backend (`ApiBackend`) so CLI works while `tj serve` holds the DB lock
112
+
113
+ ### Changed
114
+ - README: added toy agent quick-start, example agents section, corrected metrics URL, updated CLI reference
115
+ - CLAUDE.md: updated CLI command table, repo layout, added PyPI package name rule
116
+
117
+ ## [0.1.1] - 2026-04-06
118
+
119
+ ### Fixed
120
+ - `tj export` returning empty output due to corrupted DuckDB span indexes
121
+ - `tj status` showing `?` instead of `●` for completed sessions
122
+ - `tj status` showing `$0.000000` cost due to `date.today()` vs UTC date mismatch
123
+ - `tj cost` showing spurious `$0.000000` row from session-level spans with no model
124
+
125
+ ### Added
126
+ - `tj trace` prefix matching — short trace IDs now resolve like git short hashes
127
+ - PyPI and npm publish workflows (`publish-pypi.yml`, `publish-npm.yml`)
128
+ - PyPI metadata: README as long description, classifiers, project URLs
129
+ - `CODEOWNERS` requiring review from @anilmurty
130
+
131
+ ### Changed
132
+ - Renamed npm package from `@tokenjam/sdk` to `@tokenjam/sdk`
133
+ - Consolidated `AGENTS.md` to point at `CLAUDE.md` as source of truth
134
+
135
+ ## [0.1.0] - 2026-04-05
136
+
137
+ ### Added
138
+ - Core observability pipeline: span ingestion, session tracking, cost calculation
139
+ - DuckDB storage backend with migration runner
140
+ - 13 alert types with 6 dispatch channels (stdout, file, ntfy, webhook, Discord, Telegram)
141
+ - Z-score behavioral drift detection with automatic baseline building
142
+ - JSON Schema validation for tool outputs (declared or genson-inferred)
143
+ - CLI commands: `onboard`, `status`, `traces`, `cost`, `alerts`, `drift`, `tools`, `export`, `serve`, `doctor`
144
+ - REST API with OTLP JSON ingest endpoint and Prometheus metrics
145
+ - Python SDK: `@watch()` decorator, `patch_anthropic()`, `patch_openai()`, and 9 more provider/framework integrations
146
+ - TypeScript SDK (`@tokenjam/sdk`): `TjClient` and `SpanBuilder` for Node.js agents
147
+ - Auto-bootstrap: TracerProvider initializes lazily on first `@watch()` or `patch_*()` call
148
+ - Community-maintained model pricing table (`pricing/models.toml`)
149
+ - Session continuity via `conversation_id` across process restarts
150
+ - GitHub Actions CI (Python 3.10/3.11/3.12 + TypeScript)