tracesage 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 (180) hide show
  1. tracesage-0.1.0/.gitignore +70 -0
  2. tracesage-0.1.0/LICENSE +21 -0
  3. tracesage-0.1.0/PKG-INFO +374 -0
  4. tracesage-0.1.0/README.md +320 -0
  5. tracesage-0.1.0/docs/.gitkeep +0 -0
  6. tracesage-0.1.0/docs/api.md +186 -0
  7. tracesage-0.1.0/docs/changelog.md +111 -0
  8. tracesage-0.1.0/docs/cli.md +199 -0
  9. tracesage-0.1.0/docs/comparison.md +75 -0
  10. tracesage-0.1.0/docs/concepts.md +304 -0
  11. tracesage-0.1.0/docs/configuration.md +97 -0
  12. tracesage-0.1.0/docs/contributing.md +69 -0
  13. tracesage-0.1.0/docs/development.md +144 -0
  14. tracesage-0.1.0/docs/examples.md +62 -0
  15. tracesage-0.1.0/docs/extending.md +94 -0
  16. tracesage-0.1.0/docs/index.md +92 -0
  17. tracesage-0.1.0/docs/mcp.md +85 -0
  18. tracesage-0.1.0/docs/production.md +202 -0
  19. tracesage-0.1.0/docs/quickstart.md +146 -0
  20. tracesage-0.1.0/docs/releasing.md +545 -0
  21. tracesage-0.1.0/examples/README.md +51 -0
  22. tracesage-0.1.0/examples/getting_started/01_smart_search_agent.py +153 -0
  23. tracesage-0.1.0/examples/getting_started/02_research_supervisor.py +185 -0
  24. tracesage-0.1.0/examples/getting_started/03_rag_with_tools.py +186 -0
  25. tracesage-0.1.0/examples/mcp/README.md +75 -0
  26. tracesage-0.1.0/examples/mcp/local_only.py +111 -0
  27. tracesage-0.1.0/examples/mcp/main.py +166 -0
  28. tracesage-0.1.0/examples/mcp/math_server.py +26 -0
  29. tracesage-0.1.0/examples/mcp/mcp_only.py +107 -0
  30. tracesage-0.1.0/examples/mcp/single_agent_multi_mcp.py +104 -0
  31. tracesage-0.1.0/examples/mcp/weather_server.py +43 -0
  32. tracesage-0.1.0/examples/showcase/01_support_faq_router/README.md +35 -0
  33. tracesage-0.1.0/examples/showcase/01_support_faq_router/after.py +93 -0
  34. tracesage-0.1.0/examples/showcase/01_support_faq_router/before.py +86 -0
  35. tracesage-0.1.0/examples/showcase/02_web_research_agent/README.md +30 -0
  36. tracesage-0.1.0/examples/showcase/02_web_research_agent/after.py +62 -0
  37. tracesage-0.1.0/examples/showcase/02_web_research_agent/before.py +55 -0
  38. tracesage-0.1.0/examples/showcase/03_text_to_sql_analyst/README.md +31 -0
  39. tracesage-0.1.0/examples/showcase/03_text_to_sql_analyst/after.py +105 -0
  40. tracesage-0.1.0/examples/showcase/03_text_to_sql_analyst/before.py +99 -0
  41. tracesage-0.1.0/examples/showcase/04_marketing_copy/README.md +28 -0
  42. tracesage-0.1.0/examples/showcase/04_marketing_copy/after.py +68 -0
  43. tracesage-0.1.0/examples/showcase/04_marketing_copy/before.py +61 -0
  44. tracesage-0.1.0/examples/showcase/05_content_safety/README.md +28 -0
  45. tracesage-0.1.0/examples/showcase/05_content_safety/after.py +71 -0
  46. tracesage-0.1.0/examples/showcase/05_content_safety/before.py +64 -0
  47. tracesage-0.1.0/examples/showcase/06_internal_docs_qa/README.md +41 -0
  48. tracesage-0.1.0/examples/showcase/06_internal_docs_qa/after.py +89 -0
  49. tracesage-0.1.0/examples/showcase/06_internal_docs_qa/before.py +83 -0
  50. tracesage-0.1.0/examples/showcase/07_multi_query_rag/README.md +43 -0
  51. tracesage-0.1.0/examples/showcase/07_multi_query_rag/after.py +129 -0
  52. tracesage-0.1.0/examples/showcase/07_multi_query_rag/before.py +120 -0
  53. tracesage-0.1.0/examples/showcase/08_agentic_rag/README.md +37 -0
  54. tracesage-0.1.0/examples/showcase/08_agentic_rag/after.py +139 -0
  55. tracesage-0.1.0/examples/showcase/08_agentic_rag/before.py +133 -0
  56. tracesage-0.1.0/examples/showcase/09_rag_reranker/README.md +46 -0
  57. tracesage-0.1.0/examples/showcase/09_rag_reranker/after.py +113 -0
  58. tracesage-0.1.0/examples/showcase/09_rag_reranker/before.py +106 -0
  59. tracesage-0.1.0/examples/showcase/10_conversational_rag/README.md +41 -0
  60. tracesage-0.1.0/examples/showcase/10_conversational_rag/after.py +123 -0
  61. tracesage-0.1.0/examples/showcase/10_conversational_rag/before.py +115 -0
  62. tracesage-0.1.0/examples/showcase/11_supervisor_research_team/README.md +41 -0
  63. tracesage-0.1.0/examples/showcase/11_supervisor_research_team/after.py +124 -0
  64. tracesage-0.1.0/examples/showcase/11_supervisor_research_team/before.py +116 -0
  65. tracesage-0.1.0/examples/showcase/12_hierarchical_writing/README.md +42 -0
  66. tracesage-0.1.0/examples/showcase/12_hierarchical_writing/after.py +107 -0
  67. tracesage-0.1.0/examples/showcase/12_hierarchical_writing/before.py +100 -0
  68. tracesage-0.1.0/examples/showcase/13_support_triage_specialists/README.md +43 -0
  69. tracesage-0.1.0/examples/showcase/13_support_triage_specialists/after.py +116 -0
  70. tracesage-0.1.0/examples/showcase/13_support_triage_specialists/before.py +110 -0
  71. tracesage-0.1.0/examples/showcase/14_competitive_intel_crew/README.md +39 -0
  72. tracesage-0.1.0/examples/showcase/14_competitive_intel_crew/after.py +116 -0
  73. tracesage-0.1.0/examples/showcase/14_competitive_intel_crew/before.py +109 -0
  74. tracesage-0.1.0/examples/showcase/15_code_migration_crew/README.md +37 -0
  75. tracesage-0.1.0/examples/showcase/15_code_migration_crew/after.py +107 -0
  76. tracesage-0.1.0/examples/showcase/15_code_migration_crew/before.py +100 -0
  77. tracesage-0.1.0/examples/showcase/16_sales_lead_enrichment/README.md +38 -0
  78. tracesage-0.1.0/examples/showcase/16_sales_lead_enrichment/after.py +116 -0
  79. tracesage-0.1.0/examples/showcase/16_sales_lead_enrichment/before.py +108 -0
  80. tracesage-0.1.0/examples/showcase/17_debate_to_decision/README.md +39 -0
  81. tracesage-0.1.0/examples/showcase/17_debate_to_decision/after.py +118 -0
  82. tracesage-0.1.0/examples/showcase/17_debate_to_decision/before.py +110 -0
  83. tracesage-0.1.0/examples/showcase/18_personal_assistant_mcp/README.md +46 -0
  84. tracesage-0.1.0/examples/showcase/18_personal_assistant_mcp/after.py +99 -0
  85. tracesage-0.1.0/examples/showcase/18_personal_assistant_mcp/before.py +92 -0
  86. tracesage-0.1.0/examples/showcase/18_personal_assistant_mcp/notes_server.py +29 -0
  87. tracesage-0.1.0/examples/showcase/18_personal_assistant_mcp/tasks_server.py +29 -0
  88. tracesage-0.1.0/examples/showcase/19_github_issue_triage/README.md +37 -0
  89. tracesage-0.1.0/examples/showcase/19_github_issue_triage/after.py +100 -0
  90. tracesage-0.1.0/examples/showcase/19_github_issue_triage/before.py +94 -0
  91. tracesage-0.1.0/examples/showcase/20_multi_mcp_travel/README.md +45 -0
  92. tracesage-0.1.0/examples/showcase/20_multi_mcp_travel/after.py +90 -0
  93. tracesage-0.1.0/examples/showcase/20_multi_mcp_travel/before.py +83 -0
  94. tracesage-0.1.0/examples/showcase/20_multi_mcp_travel/flights_server.py +26 -0
  95. tracesage-0.1.0/examples/showcase/20_multi_mcp_travel/weather_server.py +26 -0
  96. tracesage-0.1.0/examples/showcase/21_devops_incident_responder/README.md +37 -0
  97. tracesage-0.1.0/examples/showcase/21_devops_incident_responder/after.py +97 -0
  98. tracesage-0.1.0/examples/showcase/21_devops_incident_responder/before.py +88 -0
  99. tracesage-0.1.0/examples/showcase/22_ecommerce_concierge/README.md +41 -0
  100. tracesage-0.1.0/examples/showcase/22_ecommerce_concierge/after.py +103 -0
  101. tracesage-0.1.0/examples/showcase/22_ecommerce_concierge/before.py +96 -0
  102. tracesage-0.1.0/examples/showcase/23_reflexion_writer/README.md +37 -0
  103. tracesage-0.1.0/examples/showcase/23_reflexion_writer/after.py +115 -0
  104. tracesage-0.1.0/examples/showcase/23_reflexion_writer/before.py +107 -0
  105. tracesage-0.1.0/examples/showcase/24_plan_and_execute/README.md +42 -0
  106. tracesage-0.1.0/examples/showcase/24_plan_and_execute/after.py +129 -0
  107. tracesage-0.1.0/examples/showcase/24_plan_and_execute/before.py +120 -0
  108. tracesage-0.1.0/examples/showcase/25_self_correcting_codegen/README.md +41 -0
  109. tracesage-0.1.0/examples/showcase/25_self_correcting_codegen/after.py +142 -0
  110. tracesage-0.1.0/examples/showcase/25_self_correcting_codegen/before.py +136 -0
  111. tracesage-0.1.0/examples/showcase/26_llm_judge_eval/README.md +45 -0
  112. tracesage-0.1.0/examples/showcase/26_llm_judge_eval/after.py +116 -0
  113. tracesage-0.1.0/examples/showcase/26_llm_judge_eval/before.py +109 -0
  114. tracesage-0.1.0/examples/showcase/26_llm_judge_eval/test_eval.py +41 -0
  115. tracesage-0.1.0/examples/showcase/27_map_reduce_summarizer/README.md +36 -0
  116. tracesage-0.1.0/examples/showcase/27_map_reduce_summarizer/after.py +101 -0
  117. tracesage-0.1.0/examples/showcase/27_map_reduce_summarizer/before.py +95 -0
  118. tracesage-0.1.0/examples/showcase/28_invoice_extractor/README.md +41 -0
  119. tracesage-0.1.0/examples/showcase/28_invoice_extractor/after.py +101 -0
  120. tracesage-0.1.0/examples/showcase/28_invoice_extractor/before.py +95 -0
  121. tracesage-0.1.0/examples/showcase/29_contract_clause_analyzer/README.md +40 -0
  122. tracesage-0.1.0/examples/showcase/29_contract_clause_analyzer/after.py +112 -0
  123. tracesage-0.1.0/examples/showcase/29_contract_clause_analyzer/before.py +104 -0
  124. tracesage-0.1.0/examples/showcase/30_insurance_claim_intake/README.md +40 -0
  125. tracesage-0.1.0/examples/showcase/30_insurance_claim_intake/after.py +130 -0
  126. tracesage-0.1.0/examples/showcase/30_insurance_claim_intake/before.py +121 -0
  127. tracesage-0.1.0/examples/showcase/README.md +104 -0
  128. tracesage-0.1.0/examples/showcase/requirements.txt +28 -0
  129. tracesage-0.1.0/production_roadmap.md +99 -0
  130. tracesage-0.1.0/pyproject.toml +137 -0
  131. tracesage-0.1.0/src/tracesage/__init__.py +26 -0
  132. tracesage-0.1.0/src/tracesage/adapters/__init__.py +8 -0
  133. tracesage-0.1.0/src/tracesage/adapters/langchain.py +1073 -0
  134. tracesage-0.1.0/src/tracesage/adapters/mcp.py +109 -0
  135. tracesage-0.1.0/src/tracesage/cli.py +881 -0
  136. tracesage-0.1.0/src/tracesage/config.py +132 -0
  137. tracesage-0.1.0/src/tracesage/models.py +177 -0
  138. tracesage-0.1.0/src/tracesage/py.typed +0 -0
  139. tracesage-0.1.0/src/tracesage/pytest_plugin.py +124 -0
  140. tracesage-0.1.0/src/tracesage/render.py +239 -0
  141. tracesage-0.1.0/src/tracesage/server/__init__.py +7 -0
  142. tracesage-0.1.0/src/tracesage/server/app.py +93 -0
  143. tracesage-0.1.0/src/tracesage/server/auth.py +112 -0
  144. tracesage-0.1.0/src/tracesage/server/rest.py +260 -0
  145. tracesage-0.1.0/src/tracesage/server/ws.py +191 -0
  146. tracesage-0.1.0/src/tracesage/storage/__init__.py +8 -0
  147. tracesage-0.1.0/src/tracesage/storage/backend.py +140 -0
  148. tracesage-0.1.0/src/tracesage/storage/blob_store.py +145 -0
  149. tracesage-0.1.0/src/tracesage/storage/sqlite_backend.py +960 -0
  150. tracesage-0.1.0/src/tracesage/tracer.py +834 -0
  151. tracesage-0.1.0/src/tracesage/ui/app.js +1946 -0
  152. tracesage-0.1.0/src/tracesage/ui/graph.js +1492 -0
  153. tracesage-0.1.0/src/tracesage/ui/index.html +330 -0
  154. tracesage-0.1.0/src/tracesage/ui/styles.css +1489 -0
  155. tracesage-0.1.0/src/tracesage/worker.py +441 -0
  156. tracesage-0.1.0/tests/__init__.py +0 -0
  157. tracesage-0.1.0/tests/conftest.py +25 -0
  158. tracesage-0.1.0/tests/integration/__init__.py +0 -0
  159. tracesage-0.1.0/tests/integration/conftest.py +72 -0
  160. tracesage-0.1.0/tests/integration/systems/__init__.py +0 -0
  161. tracesage-0.1.0/tests/integration/systems/test_system1_order_pipeline.py +196 -0
  162. tracesage-0.1.0/tests/integration/systems/test_system2_research_supervisor.py +187 -0
  163. tracesage-0.1.0/tests/integration/systems/test_system3_parallel_review.py +160 -0
  164. tracesage-0.1.0/tests/integration/systems/test_system4_writer_critic.py +162 -0
  165. tracesage-0.1.0/tests/stress/__init__.py +0 -0
  166. tracesage-0.1.0/tests/stress/conftest.py +11 -0
  167. tracesage-0.1.0/tests/stress/test_concurrent_100.py +82 -0
  168. tracesage-0.1.0/tests/test_blob_store.py +171 -0
  169. tracesage-0.1.0/tests/test_cli.py +350 -0
  170. tracesage-0.1.0/tests/test_config.py +67 -0
  171. tracesage-0.1.0/tests/test_database.py +806 -0
  172. tracesage-0.1.0/tests/test_dev_api.py +233 -0
  173. tracesage-0.1.0/tests/test_docs_contract.py +58 -0
  174. tracesage-0.1.0/tests/test_handler.py +355 -0
  175. tracesage-0.1.0/tests/test_mcp.py +234 -0
  176. tracesage-0.1.0/tests/test_pytest_plugin.py +49 -0
  177. tracesage-0.1.0/tests/test_server.py +557 -0
  178. tracesage-0.1.0/tests/test_tracer.py +333 -0
  179. tracesage-0.1.0/tests/test_worker.py +379 -0
  180. tracesage-0.1.0/tests/test_ws.py +128 -0
@@ -0,0 +1,70 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ share/python-wheels/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+ MANIFEST
24
+ evaluation
25
+
26
+ # Virtual environments
27
+ venv/
28
+ env/
29
+ ENV/
30
+ .venv/
31
+ .env
32
+
33
+ # Testing
34
+ .pytest_cache/
35
+ .coverage
36
+ .coverage.*
37
+ htmlcov/
38
+ .tox/
39
+ .nox/
40
+ coverage.xml
41
+ *.cover
42
+
43
+ # IDEs
44
+ .vscode/
45
+ .idea/
46
+ *.swp
47
+ *.swo
48
+ *~
49
+ .DS_Store
50
+
51
+ # Tooling
52
+ .ruff_cache/
53
+ .mypy_cache/
54
+
55
+ # Local data
56
+ *.db
57
+ *.db-shm
58
+ *.db-wal
59
+ .tracesage/
60
+ .tracesage-demo/
61
+ tracesage_test/
62
+ bench_data/
63
+ examples/**/mcp_demo_data/
64
+
65
+ # Build artifacts
66
+ *.tar.gz
67
+ *.whl
68
+
69
+ # MkDocs build output
70
+ site/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tracesage 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.
@@ -0,0 +1,374 @@
1
+ Metadata-Version: 2.4
2
+ Name: tracesage
3
+ Version: 0.1.0
4
+ Summary: Production observability adapter for LangChain/LangGraph multi-agent systems
5
+ Project-URL: Homepage, https://github.com/kjgpta/tracesage
6
+ Project-URL: Repository, https://github.com/kjgpta/tracesage
7
+ Project-URL: Documentation, https://kjgpta.github.io/tracesage/
8
+ Project-URL: Changelog, https://github.com/kjgpta/tracesage/blob/main/docs/changelog.md
9
+ Project-URL: Issues, https://github.com/kjgpta/tracesage/issues
10
+ Author: tracesage contributors
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: agents,langchain,langgraph,llm,multi-agent,observability,tracing
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Framework :: FastAPI
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: System :: Monitoring
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: aiofiles>=23.2.0
26
+ Requires-Dist: aiosqlite>=0.20.0
27
+ Requires-Dist: fastapi>=0.111.0
28
+ Requires-Dist: pydantic-settings>=2.3.0
29
+ Requires-Dist: pydantic>=2.7.0
30
+ Requires-Dist: typer>=0.12.0
31
+ Requires-Dist: uvicorn[standard]>=0.30.0
32
+ Requires-Dist: websockets>=12.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: build>=1.0.0; extra == 'dev'
35
+ Requires-Dist: httpx>=0.27.0; extra == 'dev'
36
+ Requires-Dist: langchain-core>=0.2.0; extra == 'dev'
37
+ Requires-Dist: langchain-mcp-adapters>=0.1.0; extra == 'dev'
38
+ Requires-Dist: langchain>=0.2.0; extra == 'dev'
39
+ Requires-Dist: langgraph>=0.2.0; extra == 'dev'
40
+ Requires-Dist: mcp>=1.0.0; extra == 'dev'
41
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
42
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
43
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
44
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
45
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
46
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
47
+ Provides-Extra: langchain
48
+ Requires-Dist: langchain-core<1.4.0,>=0.2.0; extra == 'langchain'
49
+ Provides-Extra: mcp
50
+ Requires-Dist: langchain-mcp-adapters>=0.1.0; extra == 'mcp'
51
+ Requires-Dist: langgraph>=0.2.0; extra == 'mcp'
52
+ Requires-Dist: mcp>=1.0.0; extra == 'mcp'
53
+ Description-Content-Type: text/markdown
54
+
55
+ <div align="center">
56
+
57
+ # tracesage
58
+
59
+ **Production observability for LangChain & LangGraph multi-agent systems.**
60
+ Drop in two lines, see live execution traces in your browser.
61
+
62
+ [![PyPI version](https://img.shields.io/pypi/v/tracesage.svg)](https://pypi.org/project/tracesage/)
63
+ [![Python versions](https://img.shields.io/pypi/pyversions/tracesage.svg)](https://pypi.org/project/tracesage/)
64
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
65
+ [![CI](https://github.com/kjgpta/tracesage/actions/workflows/ci.yml/badge.svg)](https://github.com/kjgpta/tracesage/actions/workflows/ci.yml)
66
+ [![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](#status)
67
+
68
+ </div>
69
+
70
+ ```python
71
+ from tracesage import TraceSage
72
+
73
+ # Illustrative only — `await` runs inside an async function. See Quick start
74
+ # below for a complete, runnable `async def main()`.
75
+ tracer = await TraceSage.create() # one-time setup
76
+
77
+ result = await graph.ainvoke(
78
+ {"input": payload},
79
+ config={"callbacks": [tracer.handler]}, # only line you add
80
+ )
81
+
82
+ # Open http://localhost:7842/ui to see the trace live
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Contents
88
+
89
+ - [Why tracesage](#why-tracesage)
90
+ - [Install](#install)
91
+ - [Quick start](#quick-start)
92
+ - [Concepts: topology node kinds](#concepts-topology-node-kinds)
93
+ - [Features](#features)
94
+ - [Examples](#examples)
95
+ - [Documentation](#documentation)
96
+ - [Comparison](#comparison)
97
+ - [Performance](#performance)
98
+ - [Status](#status)
99
+ - [Contributing](#contributing)
100
+ - [License](#license)
101
+
102
+ ---
103
+
104
+ ## Why tracesage
105
+
106
+ LangChain agents emit a rich callback stream — chain start/end, tool start/end,
107
+ LLM start/end, retrieval, errors. **tracesage** captures all of it without
108
+ changing your workflow logic, persists it locally (SQLite + gzipped blobs),
109
+ and renders it in an interactive graph + timeline UI in real time.
110
+
111
+ - **Zero infrastructure.** No Docker. No Postgres. No external services. `pip install`.
112
+ - **Two-line integration.** One callback added to your existing `ainvoke`.
113
+ - **Production-grade safety.** The handler never raises. The tracer never crashes
114
+ your pipeline.
115
+ - **Interactive graph view.** Custom SVG graph (no framework), auto-laid-out. Hover, click, replay any run.
116
+ - **MCP-aware.** Tools loaded from MCP servers are attributed by source, so you can
117
+ see which tools came from which server vs. which are hardcoded. See [docs/mcp.md](docs/mcp.md).
118
+ - **Pluggable storage.** SQLite today; Postgres / remote-collector / object-store backends planned (see [`production_roadmap.md`](production_roadmap.md)).
119
+ - **MIT licensed.** Free forever.
120
+
121
+ ## Install
122
+
123
+ ```bash
124
+ pip install tracesage[langchain]
125
+ ```
126
+
127
+ Requires **Python 3.11+**. The `[langchain]` extra pulls `langchain-core`;
128
+ that's the only mandatory third-party dep beyond the standard FastAPI /
129
+ aiosqlite / pydantic stack. If your app uses **LangGraph**, also `pip install
130
+ langgraph` (tracesage doesn't pull it).
131
+
132
+ tracesage is **provider-agnostic** — it traces LangChain's callback stream, so
133
+ OpenAI / Anthropic / local models are all captured automatically; there's no
134
+ provider setting in tracesage. Install whichever provider you use:
135
+
136
+ ```bash
137
+ pip install langchain-openai # OPENAI_API_KEY=...
138
+ pip install langchain-anthropic # ANTHROPIC_API_KEY=...
139
+ ```
140
+
141
+ For MCP tool-source attribution (loads tools from MCP servers and tags them by
142
+ source), install the `mcp` extra:
143
+
144
+ ```bash
145
+ pip install 'tracesage[mcp]'
146
+ ```
147
+
148
+ ## Quick start
149
+
150
+ **See it in 5 seconds** — seed a sample trace and open the UI:
151
+
152
+ ```bash
153
+ tracesage demo
154
+ ```
155
+
156
+ **Sync scripts / notebooks** — wrap your code; every LangChain call is captured
157
+ automatically (no `callbacks=` wiring) and a clickable trace link is printed:
158
+
159
+ ```python
160
+ import tracesage
161
+
162
+ with tracesage.trace() as tl: # starts the UI + global capture
163
+ result = agent.invoke("your input") # 🔍 tracesage: http://127.0.0.1:7842/ui/#run=...
164
+ input("Trace ready — open the printed link, then Enter to exit.") # keep the UI up
165
+ ```
166
+
167
+ (The embedded UI stops when the `with` block / process exits; traces persist to
168
+ `~/.tracesage`, so you can also reopen them later with `tracesage serve`.)
169
+
170
+ **Async apps** — use the context manager (or `await TraceSage.create()` for full control):
171
+
172
+ ```python
173
+ import asyncio
174
+ from tracesage import TraceSage
175
+
176
+ async def main():
177
+ async with TraceSage.session(install=True) as tl: # install=True → global capture
178
+ await graph.ainvoke({"input": "your payload"}, config={"tags": ["my-system"]})
179
+ await tl.flush() # ensure events are persisted
180
+ print(tl.run_url("<run_id>")) # deep link to a run
181
+
182
+ asyncio.run(main())
183
+ ```
184
+
185
+ Prefer explicit wiring? Pass `config={"callbacks": [tl.handler]}` instead of `install=True`.
186
+
187
+ That's it. Open **http://localhost:7842/ui** and explore.
188
+
189
+ ### Developer workflow
190
+
191
+ Once you have traces, debug them without leaving your terminal:
192
+
193
+ ```bash
194
+ tracesage show <run_id> # render a run as a tree in the terminal
195
+ tracesage watch <run_id> # live-tail events as they stream
196
+ tracesage diff <run_a> <run_b> # compare two runs (tokens, tools, errors)
197
+ tracesage view trace.jsonl # open an exported trace in the UI directly
198
+ ```
199
+
200
+ **Test your agents** — the `tracesage_capture` pytest fixture is auto-registered:
201
+
202
+ ```python
203
+ def test_agent_uses_search(tracesage_capture):
204
+ agent.invoke("find me a hotel")
205
+ tracesage_capture.assert_tool_called("search")
206
+ tracesage_capture.assert_no_errors()
207
+ assert tracesage_capture.total_tokens()[0] < 5000
208
+ ```
209
+
210
+ See **[`docs/development.md`](docs/development.md)** for the full developer guide, and
211
+ **[`examples/showcase/`](examples/showcase/)** for 30 before/after apps across popular use cases.
212
+
213
+ ## Concepts: topology node kinds
214
+
215
+ When you open the UI, every node in the topology graph is one of five event-based
216
+ kinds — plus a synthesized **`mcp`** node when you attribute tools to an MCP server.
217
+ Knowing what each means is the prerequisite to reading a trace:
218
+
219
+ | Kind | What it is | Examples you'll see |
220
+ |---|---|---|
221
+ | **`agent`** | A function **you** registered as a LangGraph node, that calls other components | `agent:billing_agent`, `agent:fact_extractor`, `agent:supervisor` |
222
+ | **`tool`** | A side-effect function (DB query, API call, calculation) decorated with `@tool` | `tool:lookup_account`, `tool:run_sql`, `tool:cite_sources` |
223
+ | **`llm`** | A language-model call (chat or completion) | `llm:FakeListChatModel`, `llm:ChatOpenAI`, `llm:ChatAnthropic` |
224
+ | **`retriever`** | A `BaseRetriever` subclass — the "R" in RAG | `retriever:Chroma`, `retriever:FAISS`, `retriever:_FixedCorpusRetriever` |
225
+ | **`chain`** | Plumbing — LCEL primitives, the LangGraph orchestrator, routing functions | `chain:LangGraph`, `chain:RunnableSequence`, `chain:ChatPromptTemplate`, `chain:route_after_quality` |
226
+ | **`mcp`** | An MCP server (synthesized) — groups the tools loaded from it | `mcp:weather`, `mcp:math`, `mcp:github` |
227
+
228
+ Quick mental model:
229
+
230
+ - **`agent`** is your code that *calls* something. It does reasoning.
231
+ - **`tool`** does the actual side-effect work and returns a result.
232
+ - **`llm`** is what you count, cost, and cache.
233
+ - **`retriever`** is its own dimension — "did we find the right docs?"
234
+ is a different question from "did the LLM use them well?".
235
+ - **`chain`** is the wrapping machinery (the `prompt | llm | parser`
236
+ pipe operator, the LangGraph state machine, routing functions). It's
237
+ infrastructure, not business logic.
238
+ - **`mcp`** groups tools by the MCP server they came from — provenance, so you can
239
+ tell server-provided tools from your hardcoded ones (see [docs/mcp.md](docs/mcp.md)).
240
+
241
+ Read the full reference at **[`docs/concepts.md`](docs/concepts.md)** —
242
+ it covers how tracesage classifies events into kinds, why agents with no
243
+ descendants get demoted to `chain`, and walks through a research-pipeline
244
+ topology piece by piece.
245
+
246
+ ## Features
247
+
248
+ ### Live interactive UI
249
+
250
+ - **Run list** with status badges (running / completed / failed), search, status filter
251
+ - **SVG graph** showing agents, tools, and execution paths — pulses as events arrive
252
+ - **MCP attribution** — `mcp:` server nodes with per-server colors, agent→server and
253
+ server→tool edges, and a draggable "Tools by source" panel grouping tools by origin
254
+ - **Timeline** with click-to-expand step cards, lazy-loaded full payloads
255
+ - **Replay** mode that re-animates a run at 1x / 2x / 5x speed
256
+ - **Dark / light themes**, persisted in `localStorage`
257
+ - **Keyboard shortcuts:** `j`/`k` next/prev run, `/` focus search, `t` toggle theme, `Esc`, `?`
258
+
259
+ ### Production safety
260
+
261
+ - Refuses to bind non-loopback addresses without `auth_token` (hard fail-stop)
262
+ - Bearer-token HTTP auth + WebSocket auth via `?token=` or subprotocol
263
+ - Constant-time token comparison
264
+ - Path-traversal blocked at runtime
265
+ - Per-run event cap (circuit breaker) and root-level sampling for high volumes
266
+ - Bounded internal state (no unbounded memory growth in long-running processes)
267
+ - **Kill switch:** `TRACESAGE_ENABLED=false` makes it a complete no-op (no server, no
268
+ DB/worker, no-op handler) — integrate once, disable per-environment. See
269
+ [docs/production.md](docs/production.md).
270
+
271
+ ### CLI
272
+
273
+ ```bash
274
+ tracesage serve --data-dir ~/.tracesage # read-only viewer
275
+ tracesage export --run-id RUN_ID -o trace.jsonl # export to JSONL
276
+ tracesage import -i trace.jsonl # import a JSONL export
277
+ tracesage stats --data-dir ~/.tracesage # summary stats
278
+ tracesage runs --status failed --limit 20 # list runs
279
+ tracesage gc --max-runs 10000 # retention cleanup
280
+ tracesage doctor --data-dir ~/.tracesage # data-dir diagnostics
281
+ tracesage version
282
+ ```
283
+
284
+ See [`docs/cli.md`](docs/cli.md) for full reference.
285
+
286
+ ## Examples
287
+
288
+ The [`examples/`](examples/) directory has three tiers:
289
+
290
+ - **[`getting_started/`](examples/getting_started/)** — 3 standalone demos driven by
291
+ `FakeListChatModel` (**no API key**): smart-search agent, research supervisor, RAG.
292
+ - **[`mcp/`](examples/mcp/)** — tools from 2 local MCP servers + 2 hardcoded tools,
293
+ attributed by source in the topology (needs `tracesage[mcp]`).
294
+ - **[`showcase/`](examples/showcase/)** — **30 real before/after apps** across popular use
295
+ cases (customer support, RAG, multi-agent, MCP, reasoning loops, finance/legal/insurance).
296
+ Each ships a plain `before.py` and an `after.py` with tracesage added, so `diff` shows the
297
+ exact integration.
298
+
299
+ ```bash
300
+ # instant, no key:
301
+ python examples/getting_started/01_smart_search_agent.py # then open http://localhost:7842/ui
302
+
303
+ # the real-world gallery (needs an LLM key):
304
+ pip install -r examples/showcase/requirements.txt
305
+ export OPENAI_API_KEY=...
306
+ python examples/showcase/01_support_faq_router/after.py
307
+ ```
308
+
309
+ The **[showcase gallery](examples/showcase/)** has 30 before/after apps spanning
310
+ LangChain + LangGraph: routing, parallel fan-out, the supervisor pattern, RAG variants,
311
+ writer-critic loops, map-reduce, MCP, self-correction, and finance/legal/insurance verticals.
312
+
313
+ ## Documentation
314
+
315
+ | Doc | What's in it |
316
+ |---|---|
317
+ | [Quickstart](docs/quickstart.md) | First trace in five minutes |
318
+ | [Developer guide](docs/development.md) | Trace links, sync/notebook setup, CLI debugging, pytest fixture |
319
+ | [Configuration](docs/configuration.md) | Every `TRACESAGE_*` env var explained |
320
+ | [CLI reference](docs/cli.md) | All `tracesage` subcommands |
321
+ | [Production guide](docs/production.md) | Sampling, auth, retention, deployment |
322
+ | [Comparison](docs/comparison.md) | tracesage vs LangSmith / LangFuse / Phoenix |
323
+ | [Extending tracesage](docs/extending.md) | Adding framework adapters and storage backends |
324
+ | **[Examples](examples/showcase/)** | **30 before/after apps with tracesage added** |
325
+
326
+ ## Comparison
327
+
328
+ When to use `tracesage` vs alternatives:
329
+
330
+ | | tracesage | LangSmith | LangFuse | Phoenix |
331
+ |---|---|---|---|---|
332
+ | Zero infra | ✓ | cloud / enterprise self-host | Docker + Postgres | ✓ |
333
+ | Pure pip install | ✓ | ✓ (cloud) | ✗ | ✓ |
334
+ | Live UI | ✓ | ✓ | ✓ | ✓ |
335
+ | MIT licensed | ✓ | proprietary | MIT | Elastic v2 |
336
+ | Eval framework | non-goal | ✓ | ✓ | ✓ |
337
+ | OpenTelemetry export | v0.3+ | partial | ✓ | ✓ |
338
+
339
+ See [`docs/comparison.md`](docs/comparison.md) for the full breakdown.
340
+
341
+ ## Performance
342
+
343
+ Bench results (5,000 events, 100 distinct run_ids, 20% blob-eligible):
344
+
345
+ | Platform | Sustained | p99 write | Drops |
346
+ |---|---|---|---|
347
+ | Linux x86 + NVMe | 800–1200 ev/s | 80–150 ms | 0 |
348
+ | Windows NTFS | 60–100 ev/s | 1–2 s | 0 |
349
+
350
+ Windows NTFS is the bottleneck (gzip + fsync amplification). For very high
351
+ throughput on Windows, raise `TRACESAGE_WORKER_BATCH_SIZE` to 200 and
352
+ `TRACESAGE_WORKER_BATCH_TIMEOUT` to 0.5.
353
+
354
+ ## Status
355
+
356
+ **v0.1 — alpha.** API may still shift before v1.0. Production-monitoring-ready for
357
+ single-Python-process deployments; centralized multi-process / remote-collector mode
358
+ is on the roadmap (see [`production_roadmap.md`](production_roadmap.md)).
359
+
360
+ See [the changelog](docs/changelog.md) for release notes.
361
+
362
+ ## Contributing
363
+
364
+ Issues and pull requests are welcome.
365
+
366
+ - Read [`docs/contributing.md`](docs/contributing.md) before sending a PR
367
+ - For non-trivial changes, open a [discussion](https://github.com/kjgpta/tracesage/discussions/categories/ideas) first
368
+ - Bugs and feature requests use the [issue templates](https://github.com/kjgpta/tracesage/issues/new/choose)
369
+ - Security reports: see [`SECURITY.md`](.github/SECURITY.md) — please don't open public issues for vulnerabilities
370
+ - All participation is governed by the [Code of Conduct](.github/CODE_OF_CONDUCT.md)
371
+
372
+ ## License
373
+
374
+ [MIT](LICENSE) © tracesage contributors