tokenjam 0.3.1__tar.gz → 0.3.2__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.2/PKG-INFO +275 -0
- tokenjam-0.3.2/README.md +217 -0
- tokenjam-0.3.2/docs/python-sdk.md +79 -0
- tokenjam-0.3.2/docs/typescript-sdk.md +73 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/pricing/models.toml +16 -4
- {tokenjam-0.3.1 → tokenjam-0.3.2}/pyproject.toml +1 -1
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/package.json +1 -1
- tokenjam-0.3.2/tests/unit/test_cmd_tokenmaxx.py +97 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_cost.py +17 -2
- tokenjam-0.3.2/tests/unit/test_pricing_override.py +114 -0
- tokenjam-0.3.2/tokenjam/cli/cmd_tokenmaxx.py +270 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/main.py +2 -0
- tokenjam-0.3.2/tokenjam/core/pricing.py +135 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/pricing/models.toml +14 -8
- tokenjam-0.3.1/PKG-INFO +0 -699
- tokenjam-0.3.1/README.md +0 -641
- tokenjam-0.3.1/tokenjam/core/pricing.py +0 -72
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/CODEOWNERS +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/ISSUE_TEMPLATE/integration_request.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/pull_request_template.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/workflows/ci.yml +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/workflows/publish-npm.yml +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.github/workflows/publish-pypi.yml +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/.gitignore +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/AGENTS.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/CHANGELOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/CLAUDE.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/CONTRIBUTING.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/LICENSE +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/Makefile +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/SECURITY.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/alerts.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/architecture.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/backfill/helicone.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/backfill/langfuse.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/backfill/otlp.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/backfill/overview.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/claude-code-integration.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/cli-reference.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/configuration.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/export.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/framework-support.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/installation.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/internal/specs/.gitkeep +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/nemoclaw-integration.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/openclaw.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/optimize/cache.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/optimize/downsize.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/optimize/script.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/optimize/trim.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/policy/overview.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/screenshots/tj-alerts.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/screenshots/tj-budget.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/screenshots/tj-cost.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/screenshots/tj-status.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/docs/screenshots/tj-traces.png +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/alerts_and_drift/_shared.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/alerts_and_drift/budget_breach_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/alerts_and_drift/drift_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/alerts_and_drift/sensitive_actions_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/rag_pipeline.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/research_team.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/router_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/sample_docs/agent_patterns.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/sample_docs/cost_management.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/sample_docs/observability.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/multi/sample_docs/safety.txt +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/openclaw/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_framework/autogen_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_framework/crewai_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_framework/langchain_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_framework/langgraph_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_framework/llamaindex_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_provider/anthropic_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_provider/bedrock_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_provider/gemini_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_provider/litellm_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_provider/openai_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/examples/single_provider/openai_agents_sdk_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/hallucination-drift/BLOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/hallucination-drift/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/hallucination-drift/scenario.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/retry-loop/BLOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/retry-loop/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/retry-loop/scenario.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/surprise-cost/BLOG.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/surprise-cost/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/incidents/surprise-cost/scenario.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/package-lock.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/client.test.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/client.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/index.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/semconv.test.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/semconv.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/span-builder.test.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/span-builder.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/src/types.ts +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/sdk-ts/tsconfig.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/email_agent_budget_breach.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/email_agent_drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/email_agent_loop.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/email_agent_normal.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/mock_llm.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/agents/test_mock_scenarios.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/conftest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/e2e/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/e2e/conftest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/e2e/test_real_llm.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/factories.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/fixtures/helicone_real_response.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/fixtures/langfuse_real_response.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/fixtures/otlp_sample.json +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/test_api.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/test_cli.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/test_db.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/test_demos.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/test_full_pipeline.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/integration/test_logs_api.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/manual-new-release-tests.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/manual-pre-release-testing.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/synthetic/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/synthetic/test_alert_rules.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/synthetic/test_cost_tracking.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/synthetic/test_drift_detection.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/synthetic/test_ingest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/synthetic/test_schema_validation.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/toy_agent/toy_agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_backfill.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_cache_efficacy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_cache_recommend.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_cmd_policy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_cmd_stop.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_compare.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_config.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_config_secret_divergence.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_demo_env.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_demo_scenarios.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_export_claude_code.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_formatting.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_ingest_helicone.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_ingest_langfuse.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_ingest_otlp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_litellm_client.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_litellm_integration.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_logs_converter.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_mcp_server.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_models.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_onboard_codex.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_onboard_daemon.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_openclaw_ingest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_optimize.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_prompt_bloat.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_spans_stats_repair.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_time_parse.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_transport_401.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tests/unit/test_workflow_restructure.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/app.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/deps.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/middleware.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/agents.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/budget.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/cost.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/cost_compare.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/logs.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/metrics.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/optimize.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/otlp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/spans.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/status.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/tools.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/api/routes/traces.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_backfill.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_budget.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_cost.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_demo.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_doctor.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_export.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_mcp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_onboard.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_optimize.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_policy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_report.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_serve.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_status.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_stop.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_tools.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_traces.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/cli/cmd_uninstall.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/alerts.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/api_backend.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/backfill.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/config.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/cost.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/db.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/drift.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/export/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/export/claude_code.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/ingest.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/ingest_adapters/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/ingest_adapters/helicone.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/ingest_adapters/langfuse.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/ingest_adapters/otlp.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/models.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/README.md +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/budget_projection.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/cache_efficacy.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/cache_recommend.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/model_downgrade.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/prompt_bloat.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/analyzers/workflow_restructure.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/registry.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/runner.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/optimize/types.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/retention.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/core/schema_validator.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/demo/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/demo/env.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/mcp/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/mcp/server.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/otel/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/otel/exporters.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/otel/otlp_parsing.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/otel/provider.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/otel/semconv.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/py.typed +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/agent.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/bootstrap.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/client.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/http_exporter.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/anthropic.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/autogen.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/base.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/bedrock.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/crewai.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/gemini.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/langchain.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/langgraph.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/litellm.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/llamaindex.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/nemoclaw.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/openai.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/integrations/openai_agents_sdk.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/sdk/transport.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/ui/index.html +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/utils/__init__.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/utils/formatting.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/utils/ids.py +0 -0
- {tokenjam-0.3.1 → tokenjam-0.3.2}/tokenjam/utils/time_parse.py +0 -0
tokenjam-0.3.2/PKG-INFO
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tokenjam
|
|
3
|
+
Version: 0.3.2
|
|
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.2/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).
|
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
# Prices in USD per million tokens.
|
|
3
3
|
# Submit a PR when provider prices change.
|
|
4
4
|
|
|
5
|
+
[anthropic.claude-opus-4-8]
|
|
6
|
+
input_per_mtok = 5.00
|
|
7
|
+
output_per_mtok = 25.00
|
|
8
|
+
cache_read_per_mtok = 0.50
|
|
9
|
+
cache_write_per_mtok = 6.25
|
|
10
|
+
|
|
11
|
+
[anthropic.claude-opus-4-7]
|
|
12
|
+
input_per_mtok = 5.00
|
|
13
|
+
output_per_mtok = 25.00
|
|
14
|
+
cache_read_per_mtok = 0.50
|
|
15
|
+
cache_write_per_mtok = 6.25
|
|
16
|
+
|
|
5
17
|
[anthropic.claude-opus-4-6]
|
|
6
|
-
input_per_mtok =
|
|
7
|
-
output_per_mtok =
|
|
8
|
-
cache_read_per_mtok =
|
|
9
|
-
cache_write_per_mtok =
|
|
18
|
+
input_per_mtok = 5.00
|
|
19
|
+
output_per_mtok = 25.00
|
|
20
|
+
cache_read_per_mtok = 0.50
|
|
21
|
+
cache_write_per_mtok = 6.25
|
|
10
22
|
|
|
11
23
|
[anthropic.claude-sonnet-4-6]
|
|
12
24
|
input_per_mtok = 3.00
|