dexcost 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. dexcost-0.1.0/.gitignore +68 -0
  2. dexcost-0.1.0/CHANGELOG.md +96 -0
  3. dexcost-0.1.0/LICENSE +21 -0
  4. dexcost-0.1.0/Makefile +21 -0
  5. dexcost-0.1.0/PKG-INFO +250 -0
  6. dexcost-0.1.0/README.md +214 -0
  7. dexcost-0.1.0/examples/agent_cost.py +130 -0
  8. dexcost-0.1.0/examples/customer_attribution.py +74 -0
  9. dexcost-0.1.0/examples/quickstart/__main__.py +52 -0
  10. dexcost-0.1.0/examples/quickstart.py +40 -0
  11. dexcost-0.1.0/examples/waste_detection.py +81 -0
  12. dexcost-0.1.0/fixtures/batch_payload.v1.json +68 -0
  13. dexcost-0.1.0/fixtures/event_external_cost.v1.json +26 -0
  14. dexcost-0.1.0/fixtures/event_late.v1.json +24 -0
  15. dexcost-0.1.0/fixtures/event_llm_call.v1.json +26 -0
  16. dexcost-0.1.0/fixtures/ingest_request.v1.json +73 -0
  17. dexcost-0.1.0/fixtures/ingest_response.v1.json +5 -0
  18. dexcost-0.1.0/fixtures/task.v1.json +30 -0
  19. dexcost-0.1.0/pyproject.toml +179 -0
  20. dexcost-0.1.0/schemas/README.md +49 -0
  21. dexcost-0.1.0/schemas/dexcost-event.v1.json +111 -0
  22. dexcost-0.1.0/schemas/dexcost-task.v1.json +160 -0
  23. dexcost-0.1.0/src/dexcost/__init__.py +537 -0
  24. dexcost-0.1.0/src/dexcost/adapters/__init__.py +18 -0
  25. dexcost-0.1.0/src/dexcost/adapters/_netbytes.py +53 -0
  26. dexcost-0.1.0/src/dexcost/adapters/aws_lambda.py +122 -0
  27. dexcost-0.1.0/src/dexcost/adapters/browser.py +171 -0
  28. dexcost-0.1.0/src/dexcost/adapters/data/aws_lambda_pricing.json +61 -0
  29. dexcost-0.1.0/src/dexcost/adapters/http.py +810 -0
  30. dexcost-0.1.0/src/dexcost/auto_task.py +74 -0
  31. dexcost-0.1.0/src/dexcost/cgroup_reader.py +121 -0
  32. dexcost-0.1.0/src/dexcost/cgroup_walker.py +184 -0
  33. dexcost-0.1.0/src/dexcost/cli.py +222 -0
  34. dexcost-0.1.0/src/dexcost/clients.py +270 -0
  35. dexcost-0.1.0/src/dexcost/cloud_detect.py +573 -0
  36. dexcost-0.1.0/src/dexcost/compute_accountant.py +220 -0
  37. dexcost-0.1.0/src/dexcost/compute_pricing.py +624 -0
  38. dexcost-0.1.0/src/dexcost/compute_runtime.py +79 -0
  39. dexcost-0.1.0/src/dexcost/compute_wrap.py +209 -0
  40. dexcost-0.1.0/src/dexcost/config.py +111 -0
  41. dexcost-0.1.0/src/dexcost/context.py +202 -0
  42. dexcost-0.1.0/src/dexcost/data/compute_prices.json +180 -0
  43. dexcost-0.1.0/src/dexcost/data/egress_prices.json +418 -0
  44. dexcost-0.1.0/src/dexcost/data/gpu_prices.json +412 -0
  45. dexcost-0.1.0/src/dexcost/data/model_cost_map.json +37665 -0
  46. dexcost-0.1.0/src/dexcost/data/service_prices.json +2595 -0
  47. dexcost-0.1.0/src/dexcost/dev_console.py +99 -0
  48. dexcost-0.1.0/src/dexcost/egress_pricing.py +185 -0
  49. dexcost-0.1.0/src/dexcost/fargate_metadata.py +110 -0
  50. dexcost-0.1.0/src/dexcost/gpu_accountant.py +470 -0
  51. dexcost-0.1.0/src/dexcost/gpu_pricing.py +506 -0
  52. dexcost-0.1.0/src/dexcost/gpu_runtime.py +152 -0
  53. dexcost-0.1.0/src/dexcost/gpu_wrap.py +144 -0
  54. dexcost-0.1.0/src/dexcost/heuristics.py +168 -0
  55. dexcost-0.1.0/src/dexcost/instruments/__init__.py +30 -0
  56. dexcost-0.1.0/src/dexcost/instruments/anthropic.py +566 -0
  57. dexcost-0.1.0/src/dexcost/instruments/bedrock.py +579 -0
  58. dexcost-0.1.0/src/dexcost/instruments/cohere.py +544 -0
  59. dexcost-0.1.0/src/dexcost/instruments/gemini.py +430 -0
  60. dexcost-0.1.0/src/dexcost/instruments/litellm.py +594 -0
  61. dexcost-0.1.0/src/dexcost/instruments/mcp.py +608 -0
  62. dexcost-0.1.0/src/dexcost/instruments/openai.py +505 -0
  63. dexcost-0.1.0/src/dexcost/integrations/__init__.py +15 -0
  64. dexcost-0.1.0/src/dexcost/integrations/langchain.py +252 -0
  65. dexcost-0.1.0/src/dexcost/integrations/traces.py +56 -0
  66. dexcost-0.1.0/src/dexcost/models/__init__.py +23 -0
  67. dexcost-0.1.0/src/dexcost/models/_serde.py +43 -0
  68. dexcost-0.1.0/src/dexcost/models/enums.py +50 -0
  69. dexcost-0.1.0/src/dexcost/models/event.py +117 -0
  70. dexcost-0.1.0/src/dexcost/models/task.py +173 -0
  71. dexcost-0.1.0/src/dexcost/network_accountant.py +159 -0
  72. dexcost-0.1.0/src/dexcost/nvml_reader.py +315 -0
  73. dexcost-0.1.0/src/dexcost/pricing.py +389 -0
  74. dexcost-0.1.0/src/dexcost/py.typed +0 -0
  75. dexcost-0.1.0/src/dexcost/rates.py +146 -0
  76. dexcost-0.1.0/src/dexcost/redaction.py +135 -0
  77. dexcost-0.1.0/src/dexcost/scanner.py +607 -0
  78. dexcost-0.1.0/src/dexcost/schema.py +55 -0
  79. dexcost-0.1.0/src/dexcost/service_catalog.py +421 -0
  80. dexcost-0.1.0/src/dexcost/session.py +149 -0
  81. dexcost-0.1.0/src/dexcost/storage/__init__.py +14 -0
  82. dexcost-0.1.0/src/dexcost/storage/migrations.py +280 -0
  83. dexcost-0.1.0/src/dexcost/storage/protocol.py +109 -0
  84. dexcost-0.1.0/src/dexcost/storage/sqlite.py +694 -0
  85. dexcost-0.1.0/src/dexcost/sync.py +385 -0
  86. dexcost-0.1.0/src/dexcost/tracker.py +1406 -0
  87. dexcost-0.1.0/tests/__init__.py +0 -0
  88. dexcost-0.1.0/tests/conftest.py +17 -0
  89. dexcost-0.1.0/tests/test_anthropic_instrument.py +1003 -0
  90. dexcost-0.1.0/tests/test_auto_instrument.py +637 -0
  91. dexcost-0.1.0/tests/test_auto_task.py +144 -0
  92. dexcost-0.1.0/tests/test_batch_splitting.py +208 -0
  93. dexcost-0.1.0/tests/test_bedrock_instrument.py +645 -0
  94. dexcost-0.1.0/tests/test_browser_adapter.py +264 -0
  95. dexcost-0.1.0/tests/test_cgroup_reader.py +114 -0
  96. dexcost-0.1.0/tests/test_cgroup_walker.py +164 -0
  97. dexcost-0.1.0/tests/test_cli.py +225 -0
  98. dexcost-0.1.0/tests/test_clients.py +229 -0
  99. dexcost-0.1.0/tests/test_cloud_detect.py +583 -0
  100. dexcost-0.1.0/tests/test_cloud_detect_instance_type.py +158 -0
  101. dexcost-0.1.0/tests/test_cohere_instrument.py +625 -0
  102. dexcost-0.1.0/tests/test_compat_smoke.py +698 -0
  103. dexcost-0.1.0/tests/test_compute_accountant.py +181 -0
  104. dexcost-0.1.0/tests/test_compute_auto_emission_long_running.py +101 -0
  105. dexcost-0.1.0/tests/test_compute_catalog_integrity.py +181 -0
  106. dexcost-0.1.0/tests/test_compute_cross_runtime_matrix.py +182 -0
  107. dexcost-0.1.0/tests/test_compute_idle_gap.py +132 -0
  108. dexcost-0.1.0/tests/test_compute_invariants.py +130 -0
  109. dexcost-0.1.0/tests/test_compute_math_fixes.py +114 -0
  110. dexcost-0.1.0/tests/test_compute_pricing.py +313 -0
  111. dexcost-0.1.0/tests/test_compute_runtime.py +144 -0
  112. dexcost-0.1.0/tests/test_compute_wrap.py +150 -0
  113. dexcost-0.1.0/tests/test_config.py +99 -0
  114. dexcost-0.1.0/tests/test_context.py +349 -0
  115. dexcost-0.1.0/tests/test_cross_sdk_parity.py +316 -0
  116. dexcost-0.1.0/tests/test_e2e_local.py +292 -0
  117. dexcost-0.1.0/tests/test_egress_catalog_integrity.py +69 -0
  118. dexcost-0.1.0/tests/test_egress_pricing.py +112 -0
  119. dexcost-0.1.0/tests/test_endpoint_allowlist.py +50 -0
  120. dexcost-0.1.0/tests/test_error_handling.py +126 -0
  121. dexcost-0.1.0/tests/test_examples.py +94 -0
  122. dexcost-0.1.0/tests/test_fargate_metadata.py +139 -0
  123. dexcost-0.1.0/tests/test_gemini_instrument.py +536 -0
  124. dexcost-0.1.0/tests/test_gpu_accountant.py +386 -0
  125. dexcost-0.1.0/tests/test_gpu_auto_emission_and_back_fill.py +183 -0
  126. dexcost-0.1.0/tests/test_gpu_catalog_integrity.py +274 -0
  127. dexcost-0.1.0/tests/test_gpu_catalog_sync_consistency.py +55 -0
  128. dexcost-0.1.0/tests/test_gpu_cross_billing_model_matrix.py +152 -0
  129. dexcost-0.1.0/tests/test_gpu_idle_gap.py +118 -0
  130. dexcost-0.1.0/tests/test_gpu_invariants.py +150 -0
  131. dexcost-0.1.0/tests/test_gpu_pricing.py +289 -0
  132. dexcost-0.1.0/tests/test_gpu_runtime.py +213 -0
  133. dexcost-0.1.0/tests/test_gpu_sm_time_integration.py +187 -0
  134. dexcost-0.1.0/tests/test_gpu_utilization_signal_observability.py +157 -0
  135. dexcost-0.1.0/tests/test_gpu_wrap.py +195 -0
  136. dexcost-0.1.0/tests/test_http_adapter.py +293 -0
  137. dexcost-0.1.0/tests/test_http_adapter_v2.py +364 -0
  138. dexcost-0.1.0/tests/test_http_external_byte_attribution.py +148 -0
  139. dexcost-0.1.0/tests/test_init_cloud_detection_wiring.py +41 -0
  140. dexcost-0.1.0/tests/test_init_idempotent_and_fork.py +106 -0
  141. dexcost-0.1.0/tests/test_lambda_adapter.py +99 -0
  142. dexcost-0.1.0/tests/test_langchain_integration.py +240 -0
  143. dexcost-0.1.0/tests/test_litellm_instrument.py +941 -0
  144. dexcost-0.1.0/tests/test_mcp_instrument.py +365 -0
  145. dexcost-0.1.0/tests/test_migrations.py +697 -0
  146. dexcost-0.1.0/tests/test_models.py +351 -0
  147. dexcost-0.1.0/tests/test_netbytes.py +56 -0
  148. dexcost-0.1.0/tests/test_network_accountant.py +135 -0
  149. dexcost-0.1.0/tests/test_network_accountant_external.py +68 -0
  150. dexcost-0.1.0/tests/test_network_capture.py +277 -0
  151. dexcost-0.1.0/tests/test_network_config.py +22 -0
  152. dexcost-0.1.0/tests/test_network_cost_dual_invoice.py +86 -0
  153. dexcost-0.1.0/tests/test_network_cost_finalize.py +132 -0
  154. dexcost-0.1.0/tests/test_network_cost_invariants.py +66 -0
  155. dexcost-0.1.0/tests/test_network_cost_migration.py +142 -0
  156. dexcost-0.1.0/tests/test_network_finalize.py +96 -0
  157. dexcost-0.1.0/tests/test_network_init_wiring.py +38 -0
  158. dexcost-0.1.0/tests/test_network_llm_suppression.py +21 -0
  159. dexcost-0.1.0/tests/test_network_migration.py +101 -0
  160. dexcost-0.1.0/tests/test_network_suppression.py +54 -0
  161. dexcost-0.1.0/tests/test_new_api_smoke.py +148 -0
  162. dexcost-0.1.0/tests/test_new_context.py +128 -0
  163. dexcost-0.1.0/tests/test_non_llm_costs.py +426 -0
  164. dexcost-0.1.0/tests/test_nvml_reader.py +197 -0
  165. dexcost-0.1.0/tests/test_openai_instrument.py +737 -0
  166. dexcost-0.1.0/tests/test_pricing.py +613 -0
  167. dexcost-0.1.0/tests/test_pricing_refresh.py +96 -0
  168. dexcost-0.1.0/tests/test_public_api_surface.py +101 -0
  169. dexcost-0.1.0/tests/test_rates.py +521 -0
  170. dexcost-0.1.0/tests/test_recorded_events_cap.py +51 -0
  171. dexcost-0.1.0/tests/test_redaction.py +166 -0
  172. dexcost-0.1.0/tests/test_retry_detection.py +779 -0
  173. dexcost-0.1.0/tests/test_retry_heuristics.py +488 -0
  174. dexcost-0.1.0/tests/test_scanner.py +544 -0
  175. dexcost-0.1.0/tests/test_schema.py +271 -0
  176. dexcost-0.1.0/tests/test_service_catalog.py +382 -0
  177. dexcost-0.1.0/tests/test_session_grouping.py +213 -0
  178. dexcost-0.1.0/tests/test_set_api_key.py +84 -0
  179. dexcost-0.1.0/tests/test_sqlite_storage.py +396 -0
  180. dexcost-0.1.0/tests/test_streaming_response_not_drained.py +92 -0
  181. dexcost-0.1.0/tests/test_sync.py +851 -0
  182. dexcost-0.1.0/tests/test_task_gpu_cost_field.py +119 -0
  183. dexcost-0.1.0/tests/test_task_network_cost_field.py +29 -0
  184. dexcost-0.1.0/tests/test_task_network_fields.py +38 -0
  185. dexcost-0.1.0/tests/test_trace_linking.py +126 -0
  186. dexcost-0.1.0/tests/test_tracker.py +1074 -0
  187. dexcost-0.1.0/tests/test_version.py +16 -0
  188. dexcost-0.1.0/uv.lock +2614 -0
@@ -0,0 +1,68 @@
1
+ # ── Rust ─────────────────────────────────────────────
2
+ rust/target/
3
+ **/*.rs.bk
4
+ # Cargo.lock IS committed (binary + reproducible builds) — not ignored.
5
+
6
+ # ── Node / TypeScript ────────────────────────────────
7
+ node_modules/
8
+ typescript/dist/
9
+ *.tsbuildinfo
10
+ npm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+ .npm/
14
+ # package-lock.json IS committed — not ignored.
15
+
16
+ # ── Python ───────────────────────────────────────────
17
+ __pycache__/
18
+ *.py[cod]
19
+ *$py.class
20
+ *.egg-info/
21
+ python/build/
22
+ python/dist/
23
+ .pytest_cache/
24
+ .mypy_cache/
25
+ .ruff_cache/
26
+ .coverage
27
+ htmlcov/
28
+ .tox/
29
+ .venv/
30
+ venv/
31
+ env/
32
+
33
+ # ── Go ───────────────────────────────────────────────
34
+ go/bin/
35
+ *.exe
36
+ *.test
37
+ coverage.out
38
+ *.cover
39
+
40
+ # ── dexcost runtime artifacts ────────────────────────
41
+ # SQLite event buffers — created at runtime, never source.
42
+ *.db
43
+ *.sqlite
44
+ *.sqlite3
45
+ .dexcost/
46
+
47
+ # ── Secrets / environment ────────────────────────────
48
+ .env
49
+ .env.*
50
+ !.env.example
51
+
52
+ # ── Editors / OS ─────────────────────────────────────
53
+ .idea/
54
+ .vscode/
55
+ *.swp
56
+ *~
57
+ .DS_Store
58
+ Thumbs.db
59
+
60
+ # ── Logs ─────────────────────────────────────────────
61
+ *.log
62
+
63
+ # ── Claude Code local workspace ──────────────────────
64
+ # Agent worktrees are ephemeral local checkouts created by the
65
+ # Agent tool with isolation="worktree". Each agent's commits live
66
+ # on its own auto-generated branch and get merged back from the
67
+ # main repo — the worktree dirs themselves are never tracked.
68
+ .claude/worktrees/
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ All notable changes to dexcost will be documented in this file.
4
+
5
+ ## 0.1.0 (2026-05-30)
6
+
7
+
8
+ ### Features
9
+
10
+ * **cloud_detect:** broaden vendor coverage — GPU clouds, PaaS, more IaaS ([feb22fb](https://github.com/DexwoxBusiness/dexcost-sdk/commit/feb22fba4fe3e2665520bb921bcfb0bb83ee6cac))
11
+ * **cloud_detect:** cover ECS, Container Apps region, harden AWS heuristics ([1311fe2](https://github.com/DexwoxBusiness/dexcost-sdk/commit/1311fe21de8345f52f429ece019cc7d1173854ba))
12
+ * **compute:** auto-emit + back-fill compute_cost events at task finalize ([91beccc](https://github.com/DexwoxBusiness/dexcost-sdk/commit/91becccf2062ef6d50df9c48b7310577909e3338))
13
+ * **compute:** bundle compute price catalog (AWS/GCP/Azure/Vercel) ([dc4f419](https://github.com/DexwoxBusiness/dexcost-sdk/commit/dc4f41917b8a3935ecfbb6aee909959423aad440))
14
+ * **compute:** cgroup v2 file readers (cpu.stat, cpu.max, memory.{peak,max,current}) ([1609faf](https://github.com/DexwoxBusiness/dexcost-sdk/commit/1609faf1a35b64628ab31bc90d0d437bc01d223e))
15
+ * **compute:** extend CloudEnv with instance_type from IMDS (Decision [#3](https://github.com/DexwoxBusiness/dexcost-sdk/issues/3)) ([a613924](https://github.com/DexwoxBusiness/dexcost-sdk/commit/a613924f5b58e1bd3a4049f0669284d58ef4ff12))
16
+ * **compute:** Fargate ECS task metadata helper (MiB->bytes per Decision [#7](https://github.com/DexwoxBusiness/dexcost-sdk/issues/7)) ([08f2b22](https://github.com/DexwoxBusiness/dexcost-sdk/commit/08f2b22ce645b349d693b9855708cbe55cffc667))
17
+ * **compute:** per-task accountant — cgroup start/end snapshots, single event ([33cef0f](https://github.com/DexwoxBusiness/dexcost-sdk/commit/33cef0f1386b3a72a73da0b76191c8cab474b0e8))
18
+ * **compute:** pricing engine — per-billing-model math + degradation ladder ([e379f40](https://github.com/DexwoxBusiness/dexcost-sdk/commit/e379f40342e33cedba4bcd46f7e0982ce0bc32ef))
19
+ * **compute:** runtime resolver — serverless env vars > k8s > cloud_detect IaaS ([afbc007](https://github.com/DexwoxBusiness/dexcost-sdk/commit/afbc007a5bd77b3b19dd5f50076b02cc9c1ff48d))
20
+ * **compute:** serverless handler wraps + init knobs ([3babf79](https://github.com/DexwoxBusiness/dexcost-sdk/commit/3babf798f0b026a5524c91ed6dc7b07793b76439))
21
+ * **gpu:** auto-emit dual events + back-fill cost at task finalize ([56d8d43](https://github.com/DexwoxBusiness/dexcost-sdk/commit/56d8d43bf458b2f2acc6abcf06a096c331fa1754))
22
+ * **gpu:** bundle initial gpu_prices.json across four SDKs from live 2026 sources ([79c8745](https://github.com/DexwoxBusiness/dexcost-sdk/commit/79c8745026f92740c5f83d7171080ce98cf81c30))
23
+ * **gpu:** cgroup-scope classifier — Decision [#1](https://github.com/DexwoxBusiness/dexcost-sdk/issues/1) verification-gate impl ([caebcf7](https://github.com/DexwoxBusiness/dexcost-sdk/commit/caebcf7280b9fd3cc3718673d2573b92d2fe990c))
24
+ * **gpu:** EventType.{GPU_COST,GPU_UTILIZATION_SIGNAL} + Task.gpu_cost_usd + v5→v6 migration ([2785158](https://github.com/DexwoxBusiness/dexcost-sdk/commit/278515848606df368f0924c4072557b90ca70f3a))
25
+ * **gpu:** NVML library wrapper — fail-silent + NFC-normalized productName ([b5424ea](https://github.com/DexwoxBusiness/dexcost-sdk/commit/b5424ea0563de78dd773842049084996071bf690))
26
+ * **gpu:** per-task accountant — cgroup walk + NVML snapshot pair + dual emission ([0d47371](https://github.com/DexwoxBusiness/dexcost-sdk/commit/0d47371eac087ed29d3ef81bfb4ac9ce878ccedd))
27
+ * **gpu:** pricing engine — 4 billing models + 5-tier ladder + device-class fallback ([a47c58a](https://github.com/DexwoxBusiness/dexcost-sdk/commit/a47c58adceb1c5146ac74d4f1e297598a22bf43b))
28
+ * **gpu:** runtime cascade — serverless env > IaaS GPU family > NVML presence ([9bcb0c9](https://github.com/DexwoxBusiness/dexcost-sdk/commit/9bcb0c961201ad3e8c30812df18379f6a7d88152))
29
+ * **gpu:** serverless handler wraps (Modal / RunPod / Replicate) + Task._gpu ([fc0860a](https://github.com/DexwoxBusiness/dexcost-sdk/commit/fc0860a3c5eb35a5083548d283eea524dcba63d3))
30
+ * implement compute, network, and GPU cost capture & attribution ([f56f42d](https://github.com/DexwoxBusiness/dexcost-sdk/commit/f56f42d49043eea2569ea062bf2fada5cc4d1f06))
31
+ * **network-cost-v2:** add Task.network_cost_usd field ([e9c8f8e](https://github.com/DexwoxBusiness/dexcost-sdk/commit/e9c8f8ec4013e5a971a3705635620c97be7ef523))
32
+ * **network-cost-v2:** bundle egress price catalog (AWS/GCP/Azure) ([42d00d4](https://github.com/DexwoxBusiness/dexcost-sdk/commit/42d00d4b91459330acc78f8e8e494148f212283d))
33
+ * **network-cost-v2:** egress rate resolver + degradation ladder ([cb7079c](https://github.com/DexwoxBusiness/dexcost-sdk/commit/cb7079c968ee6ed2cbca1ff45de457e9b0c944fd))
34
+ * **network-cost-v2:** finalize-time egress pricing on tasks + events ([420c4c1](https://github.com/DexwoxBusiness/dexcost-sdk/commit/420c4c10e22cbd316720c88d34c4f3742ed73b4d))
35
+ * **network-cost-v2:** forward is_internal into accountant + deferred-cost marker ([c652bc3](https://github.com/DexwoxBusiness/dexcost-sdk/commit/c652bc39cd0606908fae2ad05d8491c6d3950b71))
36
+ * **network-cost-v2:** launch cloud detection from init() ([b381dd4](https://github.com/DexwoxBusiness/dexcost-sdk/commit/b381dd4c9add89ee88a47576cc135cee3f8e499d))
37
+ * **network-cost-v2:** NetworkAccountant external-byte split ([80da35b](https://github.com/DexwoxBusiness/dexcost-sdk/commit/80da35b043ad5f6745575e17e26d222b7356165d))
38
+ * **network-cost-v2:** non-blocking cloud provider/region detection ([ca3574d](https://github.com/DexwoxBusiness/dexcost-sdk/commit/ca3574dcc519a1e7d3b77ccca53381a3be3fc199))
39
+ * **network-cost-v2:** persist network_cost_usd + v4->v5 migration ([1166e51](https://github.com/DexwoxBusiness/dexcost-sdk/commit/1166e513ab571cc7583f7ee7b905b5bfd6590694))
40
+ * **network:** add context-scoped network-event suppression flag ([316df6a](https://github.com/DexwoxBusiness/dexcost-sdk/commit/316df6a53f7e06b80351c852178537fc961e89e2))
41
+ * **network:** add destination classifier + byte measurement helpers ([45d7bbd](https://github.com/DexwoxBusiness/dexcost-sdk/commit/45d7bbd452d9cc28a500c7650c8b1183807f46e5))
42
+ * **network:** add network event type ([6cce486](https://github.com/DexwoxBusiness/dexcost-sdk/commit/6cce4864d2d376219bcb182e1993190cbcf2e817))
43
+ * **network:** add network fields to Task model ([b19da30](https://github.com/DexwoxBusiness/dexcost-sdk/commit/b19da30f6ce7de7150b659eeb0480cdd42eddc37))
44
+ * **network:** add network-capture config fields ([1486d11](https://github.com/DexwoxBusiness/dexcost-sdk/commit/1486d11fca86b57aa30b4cea3f9f95a8a020b65f))
45
+ * **network:** add NetworkAccountant accumulator ([7834120](https://github.com/DexwoxBusiness/dexcost-sdk/commit/7834120d8fc7089abf360ae32661ccd5b205f80a))
46
+ * **network:** attach accountant to Task, finalize at task end ([9533942](https://github.com/DexwoxBusiness/dexcost-sdk/commit/95339422af7bd2e938b1d7342d08fb3c2adc08ce))
47
+ * **network:** HTTP adapter byte accounting + re-typed un-cataloged calls ([e0bc666](https://github.com/DexwoxBusiness/dexcost-sdk/commit/e0bc666645762a454eb6b7e44903722741c932b7))
48
+ * **network:** LLM instruments suppress duplicate network events ([8438780](https://github.com/DexwoxBusiness/dexcost-sdk/commit/843878096a0a039a25fa0f66154341b403a3f667))
49
+ * **network:** persist network fields + v3->v4 migration ([fb0de71](https://github.com/DexwoxBusiness/dexcost-sdk/commit/fb0de71ce3dbfc939566bd245b028a92f8bea0f3))
50
+ * **network:** wire network-capture config through init() ([9089154](https://github.com/DexwoxBusiness/dexcost-sdk/commit/9089154302d49daaa6eb76c08edf2bff3097edc1))
51
+ * **security:** scrub_url across all 4 SDKs (Sprint 1 Theme A, part 1) ([07d1097](https://github.com/DexwoxBusiness/dexcost-sdk/commit/07d10977eebcd77b16e409f9781058e80a5a46ce))
52
+ * **security:** wire scrub_url into URL-capture call sites (Sprint 1 Theme A, part 2) ([56b4cf9](https://github.com/DexwoxBusiness/dexcost-sdk/commit/56b4cf9845c3ecb1a12ec07b75f69c5ee549a07d))
53
+
54
+
55
+ ### Bug Fixes
56
+
57
+ * **all:** B14 — public set_api_key for auth-failure recovery across 4 SDKs (Sprint 2 Theme D / §3.2.3) ([bacfacd](https://github.com/DexwoxBusiness/dexcost-sdk/commit/bacfacd2140427bedc036c799d183bf8907794b2))
58
+ * **all:** P1 — canonical timestamp serialisation (Sprint 3 Theme F / §4.1.1) ([03064a7](https://github.com/DexwoxBusiness/dexcost-sdk/commit/03064a7bab0ae461fce2fb6f99842945b32d6e8a))
59
+ * **all:** P3/P4/P5 — parity reconciliation (Sprint 3 Theme F / §4.1.3) ([d82407f](https://github.com/DexwoxBusiness/dexcost-sdk/commit/d82407f8f7ba9b77355ea695f94f6a33342b0597))
60
+ * **cloud_detect:** correctness audit — DMI fields, GCP region, OCI region ([a2fa928](https://github.com/DexwoxBusiness/dexcost-sdk/commit/a2fa9283096a86954f746b3c2529fc5fca94c137))
61
+ * **network:** aiohttp/urllib3 status_code, thread-safe error counter, lint cleanup ([28ae48d](https://github.com/DexwoxBusiness/dexcost-sdk/commit/28ae48d6119ef26de23c2d64217675734d38cd05))
62
+ * **network:** dedupe _other bucket, clamp negative bytes, add accountant tests ([7aab6f4](https://github.com/DexwoxBusiness/dexcost-sdk/commit/7aab6f4d28d5891a40e803708246fa3581cf5720))
63
+ * **network:** honor track_network=False to disable byte capture and network events ([05d9cd4](https://github.com/DexwoxBusiness/dexcost-sdk/commit/05d9cd4344b6a8145ba9c27da797458ed7c0dca9))
64
+ * **network:** isolate init-wiring test instrumentation; document init() network params ([49a918e](https://github.com/DexwoxBusiness/dexcost-sdk/commit/49a918ee29d92336f6a6c46654c03a04c8e692fe))
65
+ * **network:** make _network non-init and copy-safe; cover failed-task finalize ([13c096d](https://github.com/DexwoxBusiness/dexcost-sdk/commit/13c096d2a8759c5744e1f7449c67396e64231a28))
66
+ * **python,rust:** Sprint 3 Theme F mediums — high-impact items (§4.3) ([c1d87a7](https://github.com/DexwoxBusiness/dexcost-sdk/commit/c1d87a70af21b624aa45e39e9a4f7fd3a2a4a713))
67
+ * **python:** B10 — init() idempotency + fork safety (Sprint 1 Theme B / §2.2.4) ([9bb5d35](https://github.com/DexwoxBusiness/dexcost-sdk/commit/9bb5d35fc93381bc0c43690f3d60a16e5fa09e9c))
68
+ * **python:** B11 — HTTP adapter skips body drain on streaming responses (Sprint 2 Theme C / §3.1.2) ([8a2f357](https://github.com/DexwoxBusiness/dexcost-sdk/commit/8a2f35728bbe257c679b4248ec59e11757ea8a16))
69
+ * **python:** B2 — GPU SM-time integration (Sprint 2 Theme C / §3.1.1) ([d37b6b5](https://github.com/DexwoxBusiness/dexcost-sdk/commit/d37b6b576bdf863348e3c4090638e68e2c3d7814))
70
+ * **python:** compute math — memory.peak per-task + vcpu reset confidence (Sprint 2 Theme C / §3.1.3 fixes 1+2) ([a72b8d2](https://github.com/DexwoxBusiness/dexcost-sdk/commit/a72b8d2b0439c1e12e6dee50ffeac7ded1d36012))
71
+ * **security:** A2 — DEXCOST_ENDPOINT https-only allow-list across all 4 SDKs (Sprint 1 Theme A / §2.1) ([64bd3dd](https://github.com/DexwoxBusiness/dexcost-sdk/commit/64bd3dd72bfde3ac475477765ecd22a09fa6f8f7))
72
+ * **storage:** re-mark sync_status='pending' on update_event ([ff96e94](https://github.com/DexwoxBusiness/dexcost-sdk/commit/ff96e94ee6885f48019f956a95ce4c0539a07f11))
73
+ * testpypi workflow and fixes ([7f28512](https://github.com/DexwoxBusiness/dexcost-sdk/commit/7f28512309abba3ba8d974c60b929746a365b24c))
74
+ * **typescript:** clear all 119 lint errors ([f4d9679](https://github.com/DexwoxBusiness/dexcost-sdk/commit/f4d967973a2ec3f69dd728c74e8acac88c1589ab))
75
+
76
+
77
+ ### Documentation
78
+
79
+ * **conventions:** Phase 2 GPU updates — §1 signal-event carve-out, §3 patterns, §8 primitive ([d7d48b6](https://github.com/DexwoxBusiness/dexcost-sdk/commit/d7d48b659c823403ac0e20569992a77b93a43764))
80
+
81
+ ## [0.1.0] - 2026-02-25
82
+
83
+ ### Added
84
+ - Task tracking: decorator, context manager, manual start/end (US-005--US-009)
85
+ - Auto-instrumentation for OpenAI, Anthropic, LiteLLM (US-012--US-014)
86
+ - Pricing engine with bundled model costs (US-010)
87
+ - Cost rates registry for non-LLM services (US-011)
88
+ - Retry detection and waste tracking (US-015)
89
+ - Standard Event Schema v1 with JSON Schema validation (US-002)
90
+ - SQLite storage with WAL mode and migrations (US-003)
91
+ - API key infrastructure with dx_live_/dx_test_ format (US-017)
92
+ - PII redaction and metadata policy (US-018)
93
+ - Background event push to Control Layer (US-016)
94
+ - Code scanner: `dexcost scan` CLI command (US-019)
95
+ - Wrapper clients: TrackedOpenAI, TrackedAnthropic (US-021)
96
+ - CLI: status, rates, scan commands
dexcost-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dexwox Innovations and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
dexcost-0.1.0/Makefile ADDED
@@ -0,0 +1,21 @@
1
+ .PHONY: lint format typecheck test build clean
2
+
3
+ lint:
4
+ ruff check src/ tests/
5
+
6
+ format:
7
+ black src/ tests/
8
+
9
+ typecheck:
10
+ mypy src/
11
+
12
+ test:
13
+ python -m pytest
14
+
15
+ build:
16
+ python -m build
17
+
18
+ clean:
19
+ rm -rf dist/ build/ *.egg-info src/*.egg-info
20
+ find . -type d -name __pycache__ -exec rm -rf {} +
21
+ find . -type f -name "*.pyc" -delete
dexcost-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,250 @@
1
+ Metadata-Version: 2.4
2
+ Name: dexcost
3
+ Version: 0.1.0
4
+ Summary: Agent Unit Economics SDK — track end-to-end business-task costs for AI agents.
5
+ Project-URL: Homepage, https://github.com/DexwoxBusiness/dexcost-sdk
6
+ Project-URL: Documentation, https://github.com/DexwoxBusiness/dexcost-sdk/blob/main/python/README.md
7
+ Project-URL: Repository, https://github.com/DexwoxBusiness/dexcost-sdk
8
+ Project-URL: Issues, https://github.com/DexwoxBusiness/dexcost-sdk/issues
9
+ Project-URL: Changelog, https://github.com/DexwoxBusiness/dexcost-sdk/blob/main/python/CHANGELOG.md
10
+ Author: Dexwox Innovations
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: agents,ai,cost-tracking,llm,observability,unit-economics
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: click>=8.1
25
+ Requires-Dist: jsonschema>=4.20
26
+ Requires-Dist: pyyaml>=6.0
27
+ Requires-Dist: wrapt>=1.16
28
+ Provides-Extra: all
29
+ Requires-Dist: anthropic>=0.18; extra == 'all'
30
+ Requires-Dist: boto3>=1.34; extra == 'all'
31
+ Requires-Dist: cohere>=5.0; extra == 'all'
32
+ Requires-Dist: google-genai>=1.0; extra == 'all'
33
+ Requires-Dist: litellm>=1.0; extra == 'all'
34
+ Requires-Dist: openai>=1.0; extra == 'all'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # dexcost
38
+
39
+ **Agent Unit Economics SDK** — track end-to-end business-task costs for AI agents.
40
+
41
+ dexcost attributes LLM calls, non-LLM service fees, and retry waste to customers, projects, and workflows so you can answer *"what does each AI task actually cost?"*
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pip install dexcost
47
+ ```
48
+
49
+ With all LLM provider SDKs:
50
+
51
+ ```bash
52
+ pip install dexcost[all]
53
+ ```
54
+
55
+ ## Quick Start
56
+
57
+ ### Global API (recommended)
58
+
59
+ ```python
60
+ import dexcost
61
+
62
+ dexcost.init(api_key="dx_live_...") # or set DEXCOST_API_KEY env var
63
+ dexcost.set_context(customer_id="acme-corp")
64
+
65
+ with dexcost.task(task_type="summarise_doc") as t:
66
+ # LLM calls are auto-captured — just use OpenAI/Anthropic/etc normally
67
+ response = openai.chat.completions.create(
68
+ model="gpt-4o",
69
+ messages=[{"role": "user", "content": "Summarise this document"}],
70
+ )
71
+
72
+ # Record non-LLM costs manually
73
+ t.record_cost(service="pdf_parser", cost_usd="0.002")
74
+
75
+ dexcost.close()
76
+ ```
77
+
78
+ ### Instance API (for multi-tracker scenarios)
79
+
80
+ ```python
81
+ from dexcost import CostTracker
82
+ from dexcost.storage.sqlite import SQLiteStorage
83
+
84
+ tracker = CostTracker(storage=SQLiteStorage("/tmp/demo.db"))
85
+
86
+ with tracker.task(task_type="summarise_doc", customer_id="acme") as t:
87
+ t.record_llm_call("openai", "gpt-4o", input_tokens=800, output_tokens=150)
88
+ t.record_cost(service="pdf_parser", cost_usd="0.002")
89
+ ```
90
+
91
+ ## Auto-Instrumentation
92
+
93
+ dexcost auto-instruments **6 LLM providers** and **5 HTTP libraries**.
94
+
95
+ ### LLM Providers
96
+
97
+ | Provider | Package | Auto-Patched Method |
98
+ |----------|---------|-------------------|
99
+ | OpenAI | `openai` | `chat.completions.create` (sync + async) |
100
+ | Anthropic | `anthropic` | `messages.create` (sync + async) |
101
+ | LiteLLM | `litellm` | `completion` / `acompletion` |
102
+ | Google Gemini | `google-genai` | `models.generate_content` |
103
+ | AWS Bedrock | `boto3` (botocore) | `invoke_model` |
104
+ | Cohere | `cohere` | `chat` / `generate` |
105
+
106
+ Every LLM call inside a tracked task is captured automatically — cost, tokens, latency, model, provider. No manual `record_llm_call` needed.
107
+
108
+ ### HTTP Libraries (Non-LLM Cost Capture)
109
+
110
+ | Library | What's Patched |
111
+ |---------|---------------|
112
+ | `requests` | `Session.send` |
113
+ | `httpx` | `Client.send` |
114
+ | `aiohttp` | `ClientSession._request` |
115
+ | `botocore` (boto3) | `URLLib3Session.send` |
116
+ | `urllib3` | `HTTPConnectionPool.urlopen` |
117
+
118
+ HTTP calls to domains in the [163-service catalog](src/dexcost/data/service_prices.json) (Pinecone, Twilio, SendGrid, Stripe, Firecrawl, Exa, etc.) are automatically captured as `external_cost` events with cost extracted from the response.
119
+
120
+ ### Controlling Instrumentation
121
+
122
+ ```python
123
+ # Instrument only specific providers
124
+ dexcost.init(auto_instrument=["openai", "gemini"])
125
+
126
+ # Disable all auto-instrumentation
127
+ dexcost.init(auto_instrument=[])
128
+
129
+ # Disable HTTP tracking
130
+ dexcost.init(track_http=False)
131
+ ```
132
+
133
+ ## Configuration
134
+
135
+ ### `dexcost.init()` Parameters
136
+
137
+ | Parameter | Type | Default | Description |
138
+ |-----------|------|---------|-------------|
139
+ | `api_key` | `str` | `DEXCOST_API_KEY` env | API key for cloud push |
140
+ | `auto_instrument` | `list[str]` | All 6 providers | Which LLM SDKs to patch |
141
+ | `track_http` | `bool` | `True` | Patch HTTP libraries for non-LLM cost capture |
142
+ | `batch_size` | `int` | `100` | Events per sync batch |
143
+ | `flush_interval` | `float` | `5.0` | Seconds between sync pushes |
144
+ | `redact_fields` | `list[str]` | `None` | Field names to redact from event details |
145
+ | `hash_customer_id` | `bool` | `False` | SHA-256 hash customer_id before storage |
146
+ | `environment` | `str` | `None` | Set to `"development"` for dev console mode |
147
+ | `storage` | `str` | `None` | Storage mode (`"local"` or auto-detect) |
148
+ | `buffer_path` | `str` | `~/.dexcost/buffer.db` | Path to local SQLite buffer |
149
+
150
+ ### Environment Variables
151
+
152
+ | Variable | Description |
153
+ |----------|-------------|
154
+ | `DEXCOST_API_KEY` | API key (if not passed to `init()`) |
155
+ | `DEXCOST_ENDPOINT` | Control Layer URL (default: `https://api.dexcost.io`) |
156
+ | `DEXCOST_ENV` | Set to `development` for dev console output |
157
+
158
+ ## Task Tracking
159
+
160
+ ### Context Manager
161
+
162
+ ```python
163
+ with dexcost.task(task_type="resolve_ticket") as t:
164
+ # All LLM/HTTP calls inside are automatically captured
165
+ pass
166
+ ```
167
+
168
+ ### Decorator
169
+
170
+ ```python
171
+ @tracker.track_task(task_type="generate_report", customer_id="acme")
172
+ def generate_report(data):
173
+ # LLM calls here are tracked
174
+ pass
175
+ ```
176
+
177
+ ### Manual Start/End
178
+
179
+ ```python
180
+ t = tracker.start_task(task_type="batch_job", customer_id="acme")
181
+ # ... do work ...
182
+ t.end(status="success")
183
+ ```
184
+
185
+ ## TrackedTask Methods
186
+
187
+ ```python
188
+ with dexcost.task(task_type="...") as t:
189
+ # Record LLM call manually (usually auto-captured)
190
+ t.record_llm_call("openai", "gpt-4o", input_tokens=800, output_tokens=150)
191
+
192
+ # Record non-LLM cost
193
+ t.record_cost(service="pinecone", cost_usd="0.001")
194
+
195
+ # Record usage (cost computed from registered rates)
196
+ t.record_usage(service="s3_storage", units=1024)
197
+
198
+ # Mark a retry
199
+ t.mark_retry(reason="rate_limit", cost_usd="0.005")
200
+
201
+ # Link to external trace
202
+ t.link_trace(provider="datadog", trace_id="abc123")
203
+ ```
204
+
205
+ ## Customer Attribution
206
+
207
+ ```python
208
+ dexcost.set_context(customer_id="acme-corp", project_id="proj-alpha")
209
+
210
+ # All tasks created after this inherit customer_id and project_id
211
+ with dexcost.task(task_type="...") as t:
212
+ pass # t.task.customer_id == "acme-corp"
213
+ ```
214
+
215
+ ## Dev Mode
216
+
217
+ Set `DEXCOST_ENV=development` or pass `environment="development"` to `init()`. In dev mode:
218
+ - Cost events are printed to the terminal
219
+ - No data is pushed to the cloud
220
+ - Useful for local development and debugging
221
+
222
+ ## CLI
223
+
224
+ ```bash
225
+ dexcost status # DB location, event count, sync status
226
+ dexcost rates --list # Show registered cost rates
227
+ dexcost scan . # Find untracked cost points in your code
228
+ dexcost scan . --generate-stubs # Generate record_cost() stubs for manual points
229
+ ```
230
+
231
+ ## Development
232
+
233
+ ```bash
234
+ pip install -e ".[all]"
235
+ pip install ruff black mypy pytest
236
+
237
+ make lint # ruff
238
+ make format # black
239
+ make typecheck # mypy strict
240
+ make test # pytest
241
+ ```
242
+
243
+ ## Privacy
244
+
245
+ When you connect to the Dexcost Control Layer, the SDK transmits usage data
246
+ subject to our [Privacy Policy](https://dexcost.io/privacy).
247
+
248
+ ## License
249
+
250
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,214 @@
1
+ # dexcost
2
+
3
+ **Agent Unit Economics SDK** — track end-to-end business-task costs for AI agents.
4
+
5
+ dexcost attributes LLM calls, non-LLM service fees, and retry waste to customers, projects, and workflows so you can answer *"what does each AI task actually cost?"*
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install dexcost
11
+ ```
12
+
13
+ With all LLM provider SDKs:
14
+
15
+ ```bash
16
+ pip install dexcost[all]
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### Global API (recommended)
22
+
23
+ ```python
24
+ import dexcost
25
+
26
+ dexcost.init(api_key="dx_live_...") # or set DEXCOST_API_KEY env var
27
+ dexcost.set_context(customer_id="acme-corp")
28
+
29
+ with dexcost.task(task_type="summarise_doc") as t:
30
+ # LLM calls are auto-captured — just use OpenAI/Anthropic/etc normally
31
+ response = openai.chat.completions.create(
32
+ model="gpt-4o",
33
+ messages=[{"role": "user", "content": "Summarise this document"}],
34
+ )
35
+
36
+ # Record non-LLM costs manually
37
+ t.record_cost(service="pdf_parser", cost_usd="0.002")
38
+
39
+ dexcost.close()
40
+ ```
41
+
42
+ ### Instance API (for multi-tracker scenarios)
43
+
44
+ ```python
45
+ from dexcost import CostTracker
46
+ from dexcost.storage.sqlite import SQLiteStorage
47
+
48
+ tracker = CostTracker(storage=SQLiteStorage("/tmp/demo.db"))
49
+
50
+ with tracker.task(task_type="summarise_doc", customer_id="acme") as t:
51
+ t.record_llm_call("openai", "gpt-4o", input_tokens=800, output_tokens=150)
52
+ t.record_cost(service="pdf_parser", cost_usd="0.002")
53
+ ```
54
+
55
+ ## Auto-Instrumentation
56
+
57
+ dexcost auto-instruments **6 LLM providers** and **5 HTTP libraries**.
58
+
59
+ ### LLM Providers
60
+
61
+ | Provider | Package | Auto-Patched Method |
62
+ |----------|---------|-------------------|
63
+ | OpenAI | `openai` | `chat.completions.create` (sync + async) |
64
+ | Anthropic | `anthropic` | `messages.create` (sync + async) |
65
+ | LiteLLM | `litellm` | `completion` / `acompletion` |
66
+ | Google Gemini | `google-genai` | `models.generate_content` |
67
+ | AWS Bedrock | `boto3` (botocore) | `invoke_model` |
68
+ | Cohere | `cohere` | `chat` / `generate` |
69
+
70
+ Every LLM call inside a tracked task is captured automatically — cost, tokens, latency, model, provider. No manual `record_llm_call` needed.
71
+
72
+ ### HTTP Libraries (Non-LLM Cost Capture)
73
+
74
+ | Library | What's Patched |
75
+ |---------|---------------|
76
+ | `requests` | `Session.send` |
77
+ | `httpx` | `Client.send` |
78
+ | `aiohttp` | `ClientSession._request` |
79
+ | `botocore` (boto3) | `URLLib3Session.send` |
80
+ | `urllib3` | `HTTPConnectionPool.urlopen` |
81
+
82
+ HTTP calls to domains in the [163-service catalog](src/dexcost/data/service_prices.json) (Pinecone, Twilio, SendGrid, Stripe, Firecrawl, Exa, etc.) are automatically captured as `external_cost` events with cost extracted from the response.
83
+
84
+ ### Controlling Instrumentation
85
+
86
+ ```python
87
+ # Instrument only specific providers
88
+ dexcost.init(auto_instrument=["openai", "gemini"])
89
+
90
+ # Disable all auto-instrumentation
91
+ dexcost.init(auto_instrument=[])
92
+
93
+ # Disable HTTP tracking
94
+ dexcost.init(track_http=False)
95
+ ```
96
+
97
+ ## Configuration
98
+
99
+ ### `dexcost.init()` Parameters
100
+
101
+ | Parameter | Type | Default | Description |
102
+ |-----------|------|---------|-------------|
103
+ | `api_key` | `str` | `DEXCOST_API_KEY` env | API key for cloud push |
104
+ | `auto_instrument` | `list[str]` | All 6 providers | Which LLM SDKs to patch |
105
+ | `track_http` | `bool` | `True` | Patch HTTP libraries for non-LLM cost capture |
106
+ | `batch_size` | `int` | `100` | Events per sync batch |
107
+ | `flush_interval` | `float` | `5.0` | Seconds between sync pushes |
108
+ | `redact_fields` | `list[str]` | `None` | Field names to redact from event details |
109
+ | `hash_customer_id` | `bool` | `False` | SHA-256 hash customer_id before storage |
110
+ | `environment` | `str` | `None` | Set to `"development"` for dev console mode |
111
+ | `storage` | `str` | `None` | Storage mode (`"local"` or auto-detect) |
112
+ | `buffer_path` | `str` | `~/.dexcost/buffer.db` | Path to local SQLite buffer |
113
+
114
+ ### Environment Variables
115
+
116
+ | Variable | Description |
117
+ |----------|-------------|
118
+ | `DEXCOST_API_KEY` | API key (if not passed to `init()`) |
119
+ | `DEXCOST_ENDPOINT` | Control Layer URL (default: `https://api.dexcost.io`) |
120
+ | `DEXCOST_ENV` | Set to `development` for dev console output |
121
+
122
+ ## Task Tracking
123
+
124
+ ### Context Manager
125
+
126
+ ```python
127
+ with dexcost.task(task_type="resolve_ticket") as t:
128
+ # All LLM/HTTP calls inside are automatically captured
129
+ pass
130
+ ```
131
+
132
+ ### Decorator
133
+
134
+ ```python
135
+ @tracker.track_task(task_type="generate_report", customer_id="acme")
136
+ def generate_report(data):
137
+ # LLM calls here are tracked
138
+ pass
139
+ ```
140
+
141
+ ### Manual Start/End
142
+
143
+ ```python
144
+ t = tracker.start_task(task_type="batch_job", customer_id="acme")
145
+ # ... do work ...
146
+ t.end(status="success")
147
+ ```
148
+
149
+ ## TrackedTask Methods
150
+
151
+ ```python
152
+ with dexcost.task(task_type="...") as t:
153
+ # Record LLM call manually (usually auto-captured)
154
+ t.record_llm_call("openai", "gpt-4o", input_tokens=800, output_tokens=150)
155
+
156
+ # Record non-LLM cost
157
+ t.record_cost(service="pinecone", cost_usd="0.001")
158
+
159
+ # Record usage (cost computed from registered rates)
160
+ t.record_usage(service="s3_storage", units=1024)
161
+
162
+ # Mark a retry
163
+ t.mark_retry(reason="rate_limit", cost_usd="0.005")
164
+
165
+ # Link to external trace
166
+ t.link_trace(provider="datadog", trace_id="abc123")
167
+ ```
168
+
169
+ ## Customer Attribution
170
+
171
+ ```python
172
+ dexcost.set_context(customer_id="acme-corp", project_id="proj-alpha")
173
+
174
+ # All tasks created after this inherit customer_id and project_id
175
+ with dexcost.task(task_type="...") as t:
176
+ pass # t.task.customer_id == "acme-corp"
177
+ ```
178
+
179
+ ## Dev Mode
180
+
181
+ Set `DEXCOST_ENV=development` or pass `environment="development"` to `init()`. In dev mode:
182
+ - Cost events are printed to the terminal
183
+ - No data is pushed to the cloud
184
+ - Useful for local development and debugging
185
+
186
+ ## CLI
187
+
188
+ ```bash
189
+ dexcost status # DB location, event count, sync status
190
+ dexcost rates --list # Show registered cost rates
191
+ dexcost scan . # Find untracked cost points in your code
192
+ dexcost scan . --generate-stubs # Generate record_cost() stubs for manual points
193
+ ```
194
+
195
+ ## Development
196
+
197
+ ```bash
198
+ pip install -e ".[all]"
199
+ pip install ruff black mypy pytest
200
+
201
+ make lint # ruff
202
+ make format # black
203
+ make typecheck # mypy strict
204
+ make test # pytest
205
+ ```
206
+
207
+ ## Privacy
208
+
209
+ When you connect to the Dexcost Control Layer, the SDK transmits usage data
210
+ subject to our [Privacy Policy](https://dexcost.io/privacy).
211
+
212
+ ## License
213
+
214
+ MIT — see [LICENSE](LICENSE).