tokenjam 0.3.1__tar.gz → 0.3.3__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.
- {tokenjam-0.3.1 → tokenjam-0.3.3}/CLAUDE.md +2 -2
- {tokenjam-0.3.1 → tokenjam-0.3.3}/CONTRIBUTING.md +2 -2
- tokenjam-0.3.3/PKG-INFO +275 -0
- tokenjam-0.3.3/README.md +217 -0
- tokenjam-0.3.3/docs/python-sdk.md +79 -0
- tokenjam-0.3.3/docs/typescript-sdk.md +73 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/pyproject.toml +1 -1
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/package.json +1 -1
- tokenjam-0.3.3/tests/unit/test_cmd_tokenmaxx.py +140 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_cost.py +32 -2
- tokenjam-0.3.3/tests/unit/test_pricing_override.py +114 -0
- tokenjam-0.3.3/tokenjam/cli/cmd_tokenmaxx.py +359 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/main.py +2 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/cost.py +1 -1
- tokenjam-0.3.3/tokenjam/core/pricing.py +135 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/pricing/models.toml +19 -13
- tokenjam-0.3.1/PKG-INFO +0 -699
- tokenjam-0.3.1/README.md +0 -641
- tokenjam-0.3.1/pricing/models.toml +0 -70
- tokenjam-0.3.1/tokenjam/core/pricing.py +0 -72
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/CODEOWNERS +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/ISSUE_TEMPLATE/integration_request.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/pull_request_template.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/workflows/ci.yml +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/workflows/publish-npm.yml +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.github/workflows/publish-pypi.yml +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/.gitignore +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/AGENTS.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/CHANGELOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/LICENSE +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/Makefile +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/SECURITY.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/alerts.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/architecture.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/backfill/helicone.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/backfill/langfuse.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/backfill/otlp.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/backfill/overview.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/claude-code-integration.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/cli-reference.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/configuration.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/export.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/framework-support.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/installation.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/internal/specs/.gitkeep +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/nemoclaw-integration.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/openclaw.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/optimize/cache.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/optimize/downsize.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/optimize/script.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/optimize/trim.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/policy/overview.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/screenshots/tj-alerts.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/screenshots/tj-budget.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/screenshots/tj-cost.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/screenshots/tj-status.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/docs/screenshots/tj-traces.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/alerts_and_drift/_shared.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/alerts_and_drift/budget_breach_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/alerts_and_drift/drift_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/alerts_and_drift/sensitive_actions_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/rag_pipeline.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/research_team.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/router_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/sample_docs/agent_patterns.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/sample_docs/cost_management.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/sample_docs/observability.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/multi/sample_docs/safety.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/openclaw/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_framework/autogen_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_framework/crewai_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_framework/langchain_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_framework/langgraph_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_framework/llamaindex_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_provider/anthropic_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_provider/bedrock_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_provider/gemini_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_provider/litellm_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_provider/openai_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/examples/single_provider/openai_agents_sdk_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/hallucination-drift/BLOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/hallucination-drift/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/hallucination-drift/scenario.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/retry-loop/BLOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/retry-loop/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/retry-loop/scenario.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/surprise-cost/BLOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/surprise-cost/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/incidents/surprise-cost/scenario.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/package-lock.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/client.test.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/client.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/index.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/semconv.test.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/semconv.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/span-builder.test.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/span-builder.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/src/types.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/sdk-ts/tsconfig.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/email_agent_budget_breach.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/email_agent_drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/email_agent_loop.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/email_agent_normal.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/mock_llm.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/agents/test_mock_scenarios.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/conftest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/e2e/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/e2e/conftest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/e2e/test_real_llm.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/factories.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/fixtures/helicone_real_response.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/fixtures/langfuse_real_response.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/fixtures/otlp_sample.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/test_api.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/test_cli.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/test_db.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/test_demos.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/test_full_pipeline.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/integration/test_logs_api.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/manual-new-release-tests.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/manual-pre-release-testing.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/synthetic/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/synthetic/test_alert_rules.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/synthetic/test_cost_tracking.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/synthetic/test_drift_detection.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/synthetic/test_ingest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/synthetic/test_schema_validation.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/toy_agent/toy_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_backfill.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_cache_efficacy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_cache_recommend.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_cmd_policy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_cmd_stop.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_compare.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_config.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_config_secret_divergence.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_demo_env.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_demo_scenarios.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_export_claude_code.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_formatting.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_ingest_helicone.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_ingest_langfuse.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_ingest_otlp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_litellm_client.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_litellm_integration.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_logs_converter.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_mcp_server.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_models.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_onboard_codex.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_onboard_daemon.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_openclaw_ingest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_optimize.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_prompt_bloat.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_spans_stats_repair.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_time_parse.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_transport_401.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tests/unit/test_workflow_restructure.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/app.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/deps.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/middleware.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/agents.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/budget.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/cost.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/cost_compare.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/logs.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/metrics.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/optimize.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/otlp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/spans.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/status.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/tools.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/api/routes/traces.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_backfill.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_budget.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_cost.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_doctor.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_export.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_mcp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_onboard.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_optimize.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_policy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_report.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_serve.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_status.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_stop.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_tools.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_traces.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/cli/cmd_uninstall.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/api_backend.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/backfill.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/config.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/db.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/export/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/export/claude_code.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/ingest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/ingest_adapters/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/ingest_adapters/helicone.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/ingest_adapters/langfuse.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/ingest_adapters/otlp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/models.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/budget_projection.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/cache_efficacy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/cache_recommend.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/model_downgrade.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/prompt_bloat.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/analyzers/workflow_restructure.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/registry.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/runner.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/optimize/types.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/retention.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/core/schema_validator.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/demo/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/demo/env.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/mcp/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/mcp/server.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/otel/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/otel/exporters.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/otel/otlp_parsing.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/otel/provider.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/otel/semconv.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/py.typed +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/bootstrap.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/client.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/http_exporter.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/anthropic.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/autogen.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/base.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/bedrock.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/crewai.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/gemini.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/langchain.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/langgraph.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/litellm.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/llamaindex.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/nemoclaw.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/openai.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/integrations/openai_agents_sdk.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/sdk/transport.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/ui/index.html +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/utils/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/utils/formatting.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/utils/ids.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.3}/tokenjam/utils/time_parse.py +0 -0
|
@@ -191,9 +191,9 @@ The Agent Incident Library at `incidents/` is separate: each scenario is a `scen
|
|
|
191
191
|
|
|
192
192
|
## Pricing
|
|
193
193
|
|
|
194
|
-
Model pricing lives in `pricing/models.toml` (USD per million tokens). Structure: `[provider.model_name]` with `input_per_mtok`, `output_per_mtok`, and optional `cache_read_per_mtok`/`cache_write_per_mtok`. Unknown models fall back to default rates ($0.50/$2.00 per MTok) with a logged warning. The pricing table is LRU-cached at process startup — restart to pick up changes.
|
|
194
|
+
Model pricing lives in `tokenjam/pricing/models.toml` (USD per million tokens) — the packaged file `core/pricing.py` loads via `PRICING_FILE = Path(__file__).parent.parent / "pricing" / "models.toml"`. There is no repo-root `pricing/` copy (it was moved into the package in v0.1.x so it ships in the wheel; editing a repo-root file would have no runtime effect). Structure: `[provider.model_name]` with `input_per_mtok`, `output_per_mtok`, and optional `cache_read_per_mtok`/`cache_write_per_mtok`. Unknown models fall back to default rates ($0.50/$2.00 per MTok) with a logged warning. The pricing table is LRU-cached at process startup — restart to pick up changes.
|
|
195
195
|
|
|
196
|
-
Pricing is community-maintained: submit a PR editing `pricing/models.toml` when provider prices change. No code changes needed — the file is loaded at runtime.
|
|
196
|
+
Pricing is community-maintained: submit a PR editing `tokenjam/pricing/models.toml` when provider prices change. No code changes needed — the file is loaded at runtime.
|
|
197
197
|
|
|
198
198
|
## CI
|
|
199
199
|
|
|
@@ -43,7 +43,7 @@ tokenjam/sdk/ @watch() decorator and provider/framework patches
|
|
|
43
43
|
tokenjam/otel/ OTel TracerProvider and span exporter wiring
|
|
44
44
|
tokenjam/utils/ Formatting, time parsing, ID generation
|
|
45
45
|
sdk-ts/src/ TypeScript SDK (@tokenjam/sdk)
|
|
46
|
-
pricing/models.toml
|
|
46
|
+
tokenjam/pricing/models.toml Community-maintained model pricing — PRs welcome here
|
|
47
47
|
tests/factories.py Span factory — use this in all synthetic tests, never
|
|
48
48
|
construct NormalizedSpan directly
|
|
49
49
|
```
|
|
@@ -57,7 +57,7 @@ This project was built using parallel Claude Code agents. The `.claude/` directo
|
|
|
57
57
|
|
|
58
58
|
## Pricing table contributions
|
|
59
59
|
|
|
60
|
-
The file `pricing/models.toml` is intentionally community-maintained. If a model is missing or prices have changed, open a PR with the update — no issue needed, just update the TOML and verify the format matches existing entries.
|
|
60
|
+
The file `tokenjam/pricing/models.toml` is intentionally community-maintained. If a model is missing or prices have changed, open a PR with the update — no issue needed, just update the TOML and verify the format matches existing entries. (This is the file the cost engine loads at runtime; there is no separate repo-root copy.)
|
|
61
61
|
|
|
62
62
|
## Reporting issues
|
|
63
63
|
|
tokenjam-0.3.3/PKG-INFO
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tokenjam
|
|
3
|
+
Version: 0.3.3
|
|
4
|
+
Summary: TokenJam — local-first OTel-native observability for Autonomous AI agents
|
|
5
|
+
Project-URL: Homepage, https://opencla.watch
|
|
6
|
+
Project-URL: Repository, https://github.com/Metabuilder-Labs/openclawwatch
|
|
7
|
+
Project-URL: Issues, https://github.com/Metabuilder-Labs/openclawwatch/issues
|
|
8
|
+
Author-email: Anil Murty <anil@metabldr.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,ai,llm,observability,opentelemetry
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Classifier: Topic :: System :: Monitoring
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: apscheduler>=3.10
|
|
23
|
+
Requires-Dist: click>=8.1
|
|
24
|
+
Requires-Dist: duckdb>=0.10
|
|
25
|
+
Requires-Dist: fastapi>=0.110
|
|
26
|
+
Requires-Dist: genson>=1.2
|
|
27
|
+
Requires-Dist: httpx>=0.27
|
|
28
|
+
Requires-Dist: jsonschema>=4.0
|
|
29
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.25
|
|
30
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.25
|
|
31
|
+
Requires-Dist: opentelemetry-exporter-prometheus>=0.46b0
|
|
32
|
+
Requires-Dist: opentelemetry-sdk>=1.25
|
|
33
|
+
Requires-Dist: pytz>=2024.1
|
|
34
|
+
Requires-Dist: rich>=13.0
|
|
35
|
+
Requires-Dist: tomli-w>=1.0
|
|
36
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
37
|
+
Requires-Dist: uvicorn>=0.27
|
|
38
|
+
Requires-Dist: websockets>=12.0
|
|
39
|
+
Provides-Extra: autogen
|
|
40
|
+
Requires-Dist: pyautogen>=0.2; extra == 'autogen'
|
|
41
|
+
Provides-Extra: bloat
|
|
42
|
+
Requires-Dist: llmlingua>=0.2; extra == 'bloat'
|
|
43
|
+
Provides-Extra: crewai
|
|
44
|
+
Requires-Dist: crewai>=0.28; extra == 'crewai'
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: httpx; extra == 'dev'
|
|
47
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
48
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
49
|
+
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
50
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
51
|
+
Provides-Extra: langchain
|
|
52
|
+
Requires-Dist: langchain>=0.2; extra == 'langchain'
|
|
53
|
+
Provides-Extra: litellm
|
|
54
|
+
Requires-Dist: litellm>=1.40; extra == 'litellm'
|
|
55
|
+
Provides-Extra: mcp
|
|
56
|
+
Requires-Dist: fastmcp; extra == 'mcp'
|
|
57
|
+
Description-Content-Type: text/markdown
|
|
58
|
+
|
|
59
|
+
<div align="center">
|
|
60
|
+
|
|
61
|
+
<img src="https://tokenjam.dev/icon.svg" alt="TokenJam" width="72" height="72">
|
|
62
|
+
|
|
63
|
+
# TokenJam
|
|
64
|
+
|
|
65
|
+
### Token Efficiency For AI Agents
|
|
66
|
+
|
|
67
|
+
TokenJam reads your agent's telemetry and tells you when to downsize, when to trim prompts, what to cache, and what to script. The result is a lower AI bill. Runs entirely on your machine.
|
|
68
|
+
|
|
69
|
+
[](https://github.com/Metabuilder-Labs/tokenjam/actions/workflows/ci.yml)
|
|
70
|
+
[](https://pypi.org/project/tokenjam/)
|
|
71
|
+
[](https://pypi.org/project/tokenjam/)
|
|
72
|
+
[](https://www.npmjs.com/package/@tokenjam/sdk)
|
|
73
|
+
[](LICENSE)
|
|
74
|
+
[](https://opentelemetry.io/docs/specs/semconv/gen-ai/)
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
pip install tokenjam
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**No cloud · No signup · No vendor lock-in**
|
|
81
|
+
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Four Analyzers. One Install.
|
|
87
|
+
|
|
88
|
+
TokenJam reads telemetry from every major agent runtime, framework, provider, and observability tool and surfaces savings across four areas.
|
|
89
|
+
|
|
90
|
+
<table>
|
|
91
|
+
<tr>
|
|
92
|
+
<td width="50%" valign="top">
|
|
93
|
+
|
|
94
|
+
### 🪶 Downsize
|
|
95
|
+
|
|
96
|
+
Flags sessions where a cheaper model in the same family is worth a look. Never claims quality equivalence — surfaces examples so you can spot-check.
|
|
97
|
+
|
|
98
|
+
<pre><code>tj optimize downsize</code></pre>
|
|
99
|
+
|
|
100
|
+
[Details →](docs/optimize/downsize.md)
|
|
101
|
+
|
|
102
|
+
</td>
|
|
103
|
+
<td width="50%" valign="top">
|
|
104
|
+
|
|
105
|
+
### 💾 Cache
|
|
106
|
+
|
|
107
|
+
Shows your current caching ratio per (provider, model) and suggests Anthropic prompt-cache breakpoints from stable prefixes in your real usage.
|
|
108
|
+
|
|
109
|
+
<pre><code>tj optimize cache</code></pre>
|
|
110
|
+
|
|
111
|
+
[Details →](docs/optimize/cache.md)
|
|
112
|
+
|
|
113
|
+
</td>
|
|
114
|
+
</tr>
|
|
115
|
+
<tr>
|
|
116
|
+
<td width="50%" valign="top">
|
|
117
|
+
|
|
118
|
+
### 📜 Script
|
|
119
|
+
|
|
120
|
+
Finds clusters of deterministic `(tool_name, arg_shape)` sequences that match the shape of work a plain script could replace.
|
|
121
|
+
|
|
122
|
+
<pre><code>tj optimize script</code></pre>
|
|
123
|
+
|
|
124
|
+
[Details →](docs/optimize/script.md)
|
|
125
|
+
|
|
126
|
+
</td>
|
|
127
|
+
<td width="50%" valign="top">
|
|
128
|
+
|
|
129
|
+
### ✂️ Trim
|
|
130
|
+
|
|
131
|
+
Predicts which regions of your prompts the model gives little weight to. Surfaces what's safe to cut.
|
|
132
|
+
|
|
133
|
+
<pre><code>tj optimize trim</code></pre>
|
|
134
|
+
|
|
135
|
+
[Details →](docs/optimize/trim.md)
|
|
136
|
+
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
</table>
|
|
140
|
+
|
|
141
|
+
Run all four with `tj optimize`. Run several with `tj optimize downsize cache trim`.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 30-second quickstart
|
|
146
|
+
|
|
147
|
+
For **Claude Code** users — zero code, auto-backfills your last 30 days:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install "tokenjam[mcp]"
|
|
151
|
+
tj onboard --claude-code
|
|
152
|
+
tj optimize # cost-saving candidates from your actual usage
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For any Python agent:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from tokenjam.sdk import watch
|
|
159
|
+
from tokenjam.sdk.integrations.anthropic import patch_anthropic
|
|
160
|
+
|
|
161
|
+
patch_anthropic()
|
|
162
|
+
|
|
163
|
+
@watch(agent_id="my-agent")
|
|
164
|
+
def run(task: str) -> str:
|
|
165
|
+
...
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
→ [Python SDK](docs/python-sdk.md) · [TypeScript SDK](docs/typescript-sdk.md) · [Codex](docs/claude-code-integration.md#codex) · [OTel-compatible agents](docs/framework-support.md)
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Why local-first matters
|
|
173
|
+
|
|
174
|
+
Your spans contain prompts, completions, tool inputs, and customer data. Shipping that to a SaaS vendor for "observability" is a data-egress decision most teams aren't ready to make.
|
|
175
|
+
|
|
176
|
+
| | TokenJam | LangSmith | Langfuse | Datadog LLM Obs |
|
|
177
|
+
|---|---|---|---|---|
|
|
178
|
+
| Signup required | ❌ | ✅ | ✅ | ✅ |
|
|
179
|
+
| Data leaves your machine | ❌ | ✅ | cloud only | ✅ |
|
|
180
|
+
| Cost-optimization analyzers (Downsize, Cache, Script, Trim) | ✅ | ❌ | ❌ | ❌ |
|
|
181
|
+
| Real-time sensitive-action alerts | ✅ | ❌ | ❌ | ❌ |
|
|
182
|
+
| Behavioral drift detection | ✅ | ❌ | ❌ | ❌ |
|
|
183
|
+
| OTel GenAI SemConv native | ✅ | partial | partial | partial |
|
|
184
|
+
| Works with any agent / framework | ✅ | LangChain-first | partial | ❌ |
|
|
185
|
+
| Free, MIT licensed | ✅ | freemium | freemium | paid |
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Web UI
|
|
190
|
+
|
|
191
|
+
`tj serve` runs a local dashboard at `http://127.0.0.1:7391/` with status, traces, cost breakdown, alerts, budget, and drift.
|
|
192
|
+
|
|
193
|
+
<table>
|
|
194
|
+
<tr>
|
|
195
|
+
<td width="50%"><img src="docs/screenshots/tj-status.png" alt="tj status page" /></td>
|
|
196
|
+
<td width="50%"><img src="docs/screenshots/tj-cost.png" alt="tj cost page" /></td>
|
|
197
|
+
</tr>
|
|
198
|
+
<tr>
|
|
199
|
+
<td width="50%"><img src="docs/screenshots/tj-traces.png" alt="tj traces page" /></td>
|
|
200
|
+
<td width="50%"><img src="docs/screenshots/tj-alerts.png" alt="tj alerts page" /></td>
|
|
201
|
+
</tr>
|
|
202
|
+
</table>
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Beyond optimization
|
|
207
|
+
|
|
208
|
+
TokenJam is also a full observability stack. The four analyzers ride on top.
|
|
209
|
+
|
|
210
|
+
- **Real-time cost tracking** — every LLM call priced as it happens
|
|
211
|
+
- **Safety alerts** — 13 alert types, 6 channels (ntfy, Discord, Telegram, webhook, file, stdout)
|
|
212
|
+
- **Behavioral drift detection** — Z-score baselines, no LLM required
|
|
213
|
+
- **Schema validation** — declare or infer JSON Schema for tool outputs
|
|
214
|
+
- **OTel-native** — point any OTLP exporter at `tj serve` and you're done
|
|
215
|
+
- **MCP server** — 14 tools letting Claude Code query its own telemetry mid-session
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## CLI
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
tj optimize # all four cost-optimization analyzers
|
|
223
|
+
tj optimize downsize # one analyzer
|
|
224
|
+
tj status # current cost, tokens, active alerts
|
|
225
|
+
tj cost --since 7d # spend by agent / model / day / tool
|
|
226
|
+
tj alerts # everything that fired while you were away
|
|
227
|
+
tj drift # behavioral drift Z-scores
|
|
228
|
+
tj backfill claude-code # ingest historical ~/.claude/projects/ sessions
|
|
229
|
+
tj serve # start the web UI + REST API
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
[Full CLI reference →](docs/cli-reference.md)
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Documentation
|
|
237
|
+
|
|
238
|
+
| Topic | Where |
|
|
239
|
+
|---|---|
|
|
240
|
+
| 🪶 Downsize / Cache / Script / Trim deep-dives | [docs/optimize/](docs/optimize/) |
|
|
241
|
+
| Claude Code & Codex integration | [docs/claude-code-integration.md](docs/claude-code-integration.md) |
|
|
242
|
+
| Python SDK reference | [docs/python-sdk.md](docs/python-sdk.md) |
|
|
243
|
+
| TypeScript SDK reference | [docs/typescript-sdk.md](docs/typescript-sdk.md) |
|
|
244
|
+
| Framework support (LangChain / CrewAI / etc.) | [docs/framework-support.md](docs/framework-support.md) |
|
|
245
|
+
| Alert channels & rule reference | [docs/alerts.md](docs/alerts.md) |
|
|
246
|
+
| Backfill from Langfuse / Helicone / OTLP | [docs/backfill/](docs/backfill/) |
|
|
247
|
+
| Configuration | [docs/configuration.md](docs/configuration.md) |
|
|
248
|
+
| Architecture deep-dive | [docs/architecture.md](docs/architecture.md) |
|
|
249
|
+
| Installation extras (Trim, framework patches) | [docs/installation.md](docs/installation.md) |
|
|
250
|
+
| Export to Grafana / Datadog / NDJSON | [docs/export.md](docs/export.md) |
|
|
251
|
+
| NemoClaw sandbox observer | [docs/nemoclaw-integration.md](docs/nemoclaw-integration.md) |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Roadmap
|
|
256
|
+
|
|
257
|
+
**Shipped in 0.3.x:** Downsize · Cache · Script · Trim · Claude Code + Codex onboarding · MCP server · Web UI · Backfill adapters (Langfuse, Helicone, OTLP) · Period comparison · Routing-config export · Read-only policy preview
|
|
258
|
+
|
|
259
|
+
**Up next:**
|
|
260
|
+
- [ ] `tj policy add | edit | apply` — unified rule surface
|
|
261
|
+
- [ ] `tj replay` — replay captured sessions against new model versions
|
|
262
|
+
- [ ] TypeScript framework patches (LangChain JS, OpenAI Agents SDK)
|
|
263
|
+
- [ ] Vercel AI SDK & Mastra integrations
|
|
264
|
+
- [ ] Docker image
|
|
265
|
+
- [ ] GitHub Actions for CI drift/cost checks
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
<div align="center">
|
|
270
|
+
|
|
271
|
+
**[tokenjam.dev](https://tokenjam.dev)** · [PyPI](https://pypi.org/project/tokenjam/) · [npm](https://www.npmjs.com/package/@tokenjam/sdk) · [Issues](https://github.com/Metabuilder-Labs/tokenjam/issues)
|
|
272
|
+
|
|
273
|
+
MIT License · Built by [Metabuilder Labs](https://github.com/Metabuilder-Labs)
|
|
274
|
+
|
|
275
|
+
</div>
|
tokenjam-0.3.3/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="https://tokenjam.dev/icon.svg" alt="TokenJam" width="72" height="72">
|
|
4
|
+
|
|
5
|
+
# TokenJam
|
|
6
|
+
|
|
7
|
+
### Token Efficiency For AI Agents
|
|
8
|
+
|
|
9
|
+
TokenJam reads your agent's telemetry and tells you when to downsize, when to trim prompts, what to cache, and what to script. The result is a lower AI bill. Runs entirely on your machine.
|
|
10
|
+
|
|
11
|
+
[](https://github.com/Metabuilder-Labs/tokenjam/actions/workflows/ci.yml)
|
|
12
|
+
[](https://pypi.org/project/tokenjam/)
|
|
13
|
+
[](https://pypi.org/project/tokenjam/)
|
|
14
|
+
[](https://www.npmjs.com/package/@tokenjam/sdk)
|
|
15
|
+
[](LICENSE)
|
|
16
|
+
[](https://opentelemetry.io/docs/specs/semconv/gen-ai/)
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
pip install tokenjam
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**No cloud · No signup · No vendor lock-in**
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Four Analyzers. One Install.
|
|
29
|
+
|
|
30
|
+
TokenJam reads telemetry from every major agent runtime, framework, provider, and observability tool and surfaces savings across four areas.
|
|
31
|
+
|
|
32
|
+
<table>
|
|
33
|
+
<tr>
|
|
34
|
+
<td width="50%" valign="top">
|
|
35
|
+
|
|
36
|
+
### 🪶 Downsize
|
|
37
|
+
|
|
38
|
+
Flags sessions where a cheaper model in the same family is worth a look. Never claims quality equivalence — surfaces examples so you can spot-check.
|
|
39
|
+
|
|
40
|
+
<pre><code>tj optimize downsize</code></pre>
|
|
41
|
+
|
|
42
|
+
[Details →](docs/optimize/downsize.md)
|
|
43
|
+
|
|
44
|
+
</td>
|
|
45
|
+
<td width="50%" valign="top">
|
|
46
|
+
|
|
47
|
+
### 💾 Cache
|
|
48
|
+
|
|
49
|
+
Shows your current caching ratio per (provider, model) and suggests Anthropic prompt-cache breakpoints from stable prefixes in your real usage.
|
|
50
|
+
|
|
51
|
+
<pre><code>tj optimize cache</code></pre>
|
|
52
|
+
|
|
53
|
+
[Details →](docs/optimize/cache.md)
|
|
54
|
+
|
|
55
|
+
</td>
|
|
56
|
+
</tr>
|
|
57
|
+
<tr>
|
|
58
|
+
<td width="50%" valign="top">
|
|
59
|
+
|
|
60
|
+
### 📜 Script
|
|
61
|
+
|
|
62
|
+
Finds clusters of deterministic `(tool_name, arg_shape)` sequences that match the shape of work a plain script could replace.
|
|
63
|
+
|
|
64
|
+
<pre><code>tj optimize script</code></pre>
|
|
65
|
+
|
|
66
|
+
[Details →](docs/optimize/script.md)
|
|
67
|
+
|
|
68
|
+
</td>
|
|
69
|
+
<td width="50%" valign="top">
|
|
70
|
+
|
|
71
|
+
### ✂️ Trim
|
|
72
|
+
|
|
73
|
+
Predicts which regions of your prompts the model gives little weight to. Surfaces what's safe to cut.
|
|
74
|
+
|
|
75
|
+
<pre><code>tj optimize trim</code></pre>
|
|
76
|
+
|
|
77
|
+
[Details →](docs/optimize/trim.md)
|
|
78
|
+
|
|
79
|
+
</td>
|
|
80
|
+
</tr>
|
|
81
|
+
</table>
|
|
82
|
+
|
|
83
|
+
Run all four with `tj optimize`. Run several with `tj optimize downsize cache trim`.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 30-second quickstart
|
|
88
|
+
|
|
89
|
+
For **Claude Code** users — zero code, auto-backfills your last 30 days:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install "tokenjam[mcp]"
|
|
93
|
+
tj onboard --claude-code
|
|
94
|
+
tj optimize # cost-saving candidates from your actual usage
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For any Python agent:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from tokenjam.sdk import watch
|
|
101
|
+
from tokenjam.sdk.integrations.anthropic import patch_anthropic
|
|
102
|
+
|
|
103
|
+
patch_anthropic()
|
|
104
|
+
|
|
105
|
+
@watch(agent_id="my-agent")
|
|
106
|
+
def run(task: str) -> str:
|
|
107
|
+
...
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
→ [Python SDK](docs/python-sdk.md) · [TypeScript SDK](docs/typescript-sdk.md) · [Codex](docs/claude-code-integration.md#codex) · [OTel-compatible agents](docs/framework-support.md)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Why local-first matters
|
|
115
|
+
|
|
116
|
+
Your spans contain prompts, completions, tool inputs, and customer data. Shipping that to a SaaS vendor for "observability" is a data-egress decision most teams aren't ready to make.
|
|
117
|
+
|
|
118
|
+
| | TokenJam | LangSmith | Langfuse | Datadog LLM Obs |
|
|
119
|
+
|---|---|---|---|---|
|
|
120
|
+
| Signup required | ❌ | ✅ | ✅ | ✅ |
|
|
121
|
+
| Data leaves your machine | ❌ | ✅ | cloud only | ✅ |
|
|
122
|
+
| Cost-optimization analyzers (Downsize, Cache, Script, Trim) | ✅ | ❌ | ❌ | ❌ |
|
|
123
|
+
| Real-time sensitive-action alerts | ✅ | ❌ | ❌ | ❌ |
|
|
124
|
+
| Behavioral drift detection | ✅ | ❌ | ❌ | ❌ |
|
|
125
|
+
| OTel GenAI SemConv native | ✅ | partial | partial | partial |
|
|
126
|
+
| Works with any agent / framework | ✅ | LangChain-first | partial | ❌ |
|
|
127
|
+
| Free, MIT licensed | ✅ | freemium | freemium | paid |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Web UI
|
|
132
|
+
|
|
133
|
+
`tj serve` runs a local dashboard at `http://127.0.0.1:7391/` with status, traces, cost breakdown, alerts, budget, and drift.
|
|
134
|
+
|
|
135
|
+
<table>
|
|
136
|
+
<tr>
|
|
137
|
+
<td width="50%"><img src="docs/screenshots/tj-status.png" alt="tj status page" /></td>
|
|
138
|
+
<td width="50%"><img src="docs/screenshots/tj-cost.png" alt="tj cost page" /></td>
|
|
139
|
+
</tr>
|
|
140
|
+
<tr>
|
|
141
|
+
<td width="50%"><img src="docs/screenshots/tj-traces.png" alt="tj traces page" /></td>
|
|
142
|
+
<td width="50%"><img src="docs/screenshots/tj-alerts.png" alt="tj alerts page" /></td>
|
|
143
|
+
</tr>
|
|
144
|
+
</table>
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Beyond optimization
|
|
149
|
+
|
|
150
|
+
TokenJam is also a full observability stack. The four analyzers ride on top.
|
|
151
|
+
|
|
152
|
+
- **Real-time cost tracking** — every LLM call priced as it happens
|
|
153
|
+
- **Safety alerts** — 13 alert types, 6 channels (ntfy, Discord, Telegram, webhook, file, stdout)
|
|
154
|
+
- **Behavioral drift detection** — Z-score baselines, no LLM required
|
|
155
|
+
- **Schema validation** — declare or infer JSON Schema for tool outputs
|
|
156
|
+
- **OTel-native** — point any OTLP exporter at `tj serve` and you're done
|
|
157
|
+
- **MCP server** — 14 tools letting Claude Code query its own telemetry mid-session
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## CLI
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
tj optimize # all four cost-optimization analyzers
|
|
165
|
+
tj optimize downsize # one analyzer
|
|
166
|
+
tj status # current cost, tokens, active alerts
|
|
167
|
+
tj cost --since 7d # spend by agent / model / day / tool
|
|
168
|
+
tj alerts # everything that fired while you were away
|
|
169
|
+
tj drift # behavioral drift Z-scores
|
|
170
|
+
tj backfill claude-code # ingest historical ~/.claude/projects/ sessions
|
|
171
|
+
tj serve # start the web UI + REST API
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
[Full CLI reference →](docs/cli-reference.md)
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Documentation
|
|
179
|
+
|
|
180
|
+
| Topic | Where |
|
|
181
|
+
|---|---|
|
|
182
|
+
| 🪶 Downsize / Cache / Script / Trim deep-dives | [docs/optimize/](docs/optimize/) |
|
|
183
|
+
| Claude Code & Codex integration | [docs/claude-code-integration.md](docs/claude-code-integration.md) |
|
|
184
|
+
| Python SDK reference | [docs/python-sdk.md](docs/python-sdk.md) |
|
|
185
|
+
| TypeScript SDK reference | [docs/typescript-sdk.md](docs/typescript-sdk.md) |
|
|
186
|
+
| Framework support (LangChain / CrewAI / etc.) | [docs/framework-support.md](docs/framework-support.md) |
|
|
187
|
+
| Alert channels & rule reference | [docs/alerts.md](docs/alerts.md) |
|
|
188
|
+
| Backfill from Langfuse / Helicone / OTLP | [docs/backfill/](docs/backfill/) |
|
|
189
|
+
| Configuration | [docs/configuration.md](docs/configuration.md) |
|
|
190
|
+
| Architecture deep-dive | [docs/architecture.md](docs/architecture.md) |
|
|
191
|
+
| Installation extras (Trim, framework patches) | [docs/installation.md](docs/installation.md) |
|
|
192
|
+
| Export to Grafana / Datadog / NDJSON | [docs/export.md](docs/export.md) |
|
|
193
|
+
| NemoClaw sandbox observer | [docs/nemoclaw-integration.md](docs/nemoclaw-integration.md) |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Roadmap
|
|
198
|
+
|
|
199
|
+
**Shipped in 0.3.x:** Downsize · Cache · Script · Trim · Claude Code + Codex onboarding · MCP server · Web UI · Backfill adapters (Langfuse, Helicone, OTLP) · Period comparison · Routing-config export · Read-only policy preview
|
|
200
|
+
|
|
201
|
+
**Up next:**
|
|
202
|
+
- [ ] `tj policy add | edit | apply` — unified rule surface
|
|
203
|
+
- [ ] `tj replay` — replay captured sessions against new model versions
|
|
204
|
+
- [ ] TypeScript framework patches (LangChain JS, OpenAI Agents SDK)
|
|
205
|
+
- [ ] Vercel AI SDK & Mastra integrations
|
|
206
|
+
- [ ] Docker image
|
|
207
|
+
- [ ] GitHub Actions for CI drift/cost checks
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
<div align="center">
|
|
212
|
+
|
|
213
|
+
**[tokenjam.dev](https://tokenjam.dev)** · [PyPI](https://pypi.org/project/tokenjam/) · [npm](https://www.npmjs.com/package/@tokenjam/sdk) · [Issues](https://github.com/Metabuilder-Labs/tokenjam/issues)
|
|
214
|
+
|
|
215
|
+
MIT License · Built by [Metabuilder Labs](https://github.com/Metabuilder-Labs)
|
|
216
|
+
|
|
217
|
+
</div>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Python SDK
|
|
2
|
+
|
|
3
|
+
For any Python agent — Anthropic, OpenAI, Gemini, Bedrock, LangChain, CrewAI, and 10+ more frameworks.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install tokenjam
|
|
9
|
+
tj onboard # creates config, generates ingest secret
|
|
10
|
+
tj doctor # verify your setup
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from tokenjam.sdk import watch
|
|
17
|
+
from tokenjam.sdk.integrations.anthropic import patch_anthropic
|
|
18
|
+
|
|
19
|
+
patch_anthropic() # auto-intercepts all Anthropic API calls
|
|
20
|
+
|
|
21
|
+
@watch(agent_id="my-agent")
|
|
22
|
+
def run(task: str) -> str:
|
|
23
|
+
# your agent code — nothing else to change
|
|
24
|
+
...
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Provider patches
|
|
28
|
+
|
|
29
|
+
Intercept at the API level. Framework-agnostic.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from tokenjam.sdk.integrations.anthropic import patch_anthropic # Anthropic
|
|
33
|
+
from tokenjam.sdk.integrations.openai import patch_openai # OpenAI
|
|
34
|
+
from tokenjam.sdk.integrations.gemini import patch_gemini # Google Gemini
|
|
35
|
+
from tokenjam.sdk.integrations.bedrock import patch_bedrock # AWS Bedrock
|
|
36
|
+
from tokenjam.sdk.integrations.litellm import patch_litellm # LiteLLM (100+ providers)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`patch_litellm()` covers all providers LiteLLM routes to (OpenAI, Anthropic, Bedrock, Vertex, Cohere, Mistral, Ollama, etc.). If you use LiteLLM, you don't need individual patches.
|
|
40
|
+
|
|
41
|
+
OpenAI-compatible providers (Groq, Together, Fireworks, xAI, Azure OpenAI) work via `patch_openai(base_url=...)`.
|
|
42
|
+
|
|
43
|
+
## Framework patches
|
|
44
|
+
|
|
45
|
+
Instrument the framework's own abstractions:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from tokenjam.sdk.integrations.langchain import patch_langchain # BaseLLM + BaseTool
|
|
49
|
+
from tokenjam.sdk.integrations.langgraph import patch_langgraph # CompiledGraph
|
|
50
|
+
from tokenjam.sdk.integrations.crewai import patch_crewai # Task + Agent
|
|
51
|
+
from tokenjam.sdk.integrations.autogen import patch_autogen # ConversableAgent
|
|
52
|
+
from tokenjam.sdk.integrations.llamaindex import patch_llamaindex # Native OTel
|
|
53
|
+
from tokenjam.sdk.integrations.openai_agents_sdk import patch_openai_agents # Native OTel
|
|
54
|
+
from tokenjam.sdk.integrations.nemoclaw import watch_nemoclaw # NemoClaw Gateway
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Full framework support guide: [docs/framework-support.md](framework-support.md)
|
|
58
|
+
|
|
59
|
+
## Manual instrumentation
|
|
60
|
+
|
|
61
|
+
If you can't (or don't want to) use a patch, record spans manually:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from tokenjam.sdk.agent import record_llm_call, record_tool_call
|
|
65
|
+
|
|
66
|
+
record_llm_call(
|
|
67
|
+
agent_id="my-agent", provider="anthropic", model="claude-opus-4-7",
|
|
68
|
+
input_tokens=450, output_tokens=120, duration_ms=1200,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
record_tool_call(
|
|
72
|
+
agent_id="my-agent", tool_name="send_email", duration_ms=300,
|
|
73
|
+
success=True,
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Examples
|
|
78
|
+
|
|
79
|
+
The [`examples/`](../examples/) directory has runnable agents for every integration. See [`examples/README.md`](../examples/README.md) for the full list.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# TypeScript SDK
|
|
2
|
+
|
|
3
|
+
For any Node.js / TypeScript agent. Sends spans to `tj serve` over HTTP — no in-process state, no patches.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @tokenjam/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`tj serve` must be running locally for the SDK to send spans. Set `TJ_INGEST_SECRET` to the secret from `~/.config/tj/config.toml`.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { TjClient, SpanBuilder } from "@tokenjam/sdk";
|
|
17
|
+
|
|
18
|
+
const client = new TjClient({
|
|
19
|
+
baseUrl: "http://127.0.0.1:7391",
|
|
20
|
+
ingestSecret: process.env.TJ_INGEST_SECRET ?? "",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const span = new SpanBuilder("invoke_agent")
|
|
24
|
+
.agentId("my-ts-agent")
|
|
25
|
+
.model("gpt-4o-mini")
|
|
26
|
+
.provider("openai")
|
|
27
|
+
.inputTokens(450)
|
|
28
|
+
.outputTokens(120)
|
|
29
|
+
.build();
|
|
30
|
+
|
|
31
|
+
await client.send([span]);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Sessions
|
|
35
|
+
|
|
36
|
+
For long-running agent sessions, use `startSession` / `endSession`:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const session = await client.startSession({ agentId: "my-ts-agent" });
|
|
40
|
+
|
|
41
|
+
// ... agent runs, sends spans tagged with session.id ...
|
|
42
|
+
|
|
43
|
+
await client.endSession(session.id);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Span builder
|
|
47
|
+
|
|
48
|
+
`SpanBuilder` follows the OTel GenAI semantic conventions:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
new SpanBuilder("invoke_agent")
|
|
52
|
+
.agentId("agent-1")
|
|
53
|
+
.sessionId("sess-abc")
|
|
54
|
+
.provider("anthropic")
|
|
55
|
+
.model("claude-opus-4-7")
|
|
56
|
+
.inputTokens(450)
|
|
57
|
+
.outputTokens(120)
|
|
58
|
+
.cacheReadTokens(0)
|
|
59
|
+
.cacheWriteTokens(0)
|
|
60
|
+
.durationMs(1200)
|
|
61
|
+
.attribute("custom.key", "value")
|
|
62
|
+
.build();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Errors and retries
|
|
66
|
+
|
|
67
|
+
The client buffers up to 1000 spans if `tj serve` is unreachable, retries with exponential backoff (3 attempts, 2s base delay), and drops the buffer on process exit.
|
|
68
|
+
|
|
69
|
+
On `401 Unauthorized`, the client fails fast (no retries) and logs the configured secret fingerprint so you can spot a mismatch with the daemon's secret.
|
|
70
|
+
|
|
71
|
+
## API
|
|
72
|
+
|
|
73
|
+
Full type signatures and parameter docs: see [`sdk-ts/README.md`](../sdk-ts/README.md).
|