aixtools 0.6.5__tar.gz → 0.9.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. {aixtools-0.6.5 → aixtools-0.9.3}/PKG-INFO +542 -293
  2. {aixtools-0.6.5 → aixtools-0.9.3}/README.md +531 -291
  3. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/_version.py +3 -3
  4. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/app.py +82 -19
  5. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/auth_middleware.py +8 -1
  6. aixtools-0.9.3/aixtools/a2a/auth_push_notification_sender.py +65 -0
  7. aixtools-0.9.3/aixtools/a2a/context_middleware.py +54 -0
  8. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/pydantic_ai_adapter/agent_executor.py +113 -84
  9. aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter/db/models.py +33 -0
  10. aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter/db/repository.py +41 -0
  11. aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter/db/storage.py +38 -0
  12. aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter/storage.py +30 -0
  13. aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter/types.py +40 -0
  14. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/remote_agent_connection.py +6 -0
  15. aixtools-0.9.3/aixtools/a2a/google_sdk/store/__init__.py +0 -0
  16. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/store/config.py +2 -0
  17. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/store/ensure_database.py +17 -17
  18. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/store/migrations/env.py +3 -2
  19. aixtools-0.9.3/aixtools/a2a/google_sdk/store/migrations/versions/027244bea7df_push_notifications_config.py +52 -0
  20. aixtools-0.9.3/aixtools/a2a/google_sdk/store/migrations/versions/1ee8d8ef55f4_pydantic_message_history.py +57 -0
  21. aixtools-0.9.3/aixtools/a2a/google_sdk/store/models.py +37 -0
  22. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/utils.py +18 -24
  23. aixtools-0.9.3/aixtools/a2a_direct_client/__init__.py +0 -0
  24. aixtools-0.9.3/aixtools/a2a_direct_client/client.py +40 -0
  25. aixtools-0.9.3/aixtools/a2a_direct_client/tool.py +198 -0
  26. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/__init__.py +4 -0
  27. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/agent.py +26 -2
  28. aixtools-0.9.3/aixtools/agents/context/data_models.py +56 -0
  29. aixtools-0.9.3/aixtools/agents/context/processors/audio.py +214 -0
  30. aixtools-0.9.3/aixtools/agents/context/processors/code.py +83 -0
  31. aixtools-0.9.3/aixtools/agents/context/processors/common.py +134 -0
  32. aixtools-0.9.3/aixtools/agents/context/processors/document.py +147 -0
  33. aixtools-0.9.3/aixtools/agents/context/processors/image.py +109 -0
  34. aixtools-0.9.3/aixtools/agents/context/processors/json.py +182 -0
  35. aixtools-0.9.3/aixtools/agents/context/processors/spreadsheet.py +443 -0
  36. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/char_grid/char_grid_detector_col.py +82 -0
  37. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/char_grid/char_grid_detector_flood.py +92 -0
  38. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/char_grid/char_grid_detector_row.py +74 -0
  39. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/char_grid/table_detector_sheet_char.py +282 -0
  40. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/char_grid/table_header_detector_char.py +177 -0
  41. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/char_grid/table_merger.py +53 -0
  42. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/table_detector_base.py +94 -0
  43. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/table_detector_char.py +30 -0
  44. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/table_region.py +173 -0
  45. aixtools-0.9.3/aixtools/agents/context/processors/table_detector/worksheet_as_char.py +310 -0
  46. aixtools-0.9.3/aixtools/agents/context/processors/tabular.py +306 -0
  47. aixtools-0.9.3/aixtools/agents/context/processors/text.py +183 -0
  48. aixtools-0.9.3/aixtools/agents/context/processors/xml.py +124 -0
  49. aixtools-0.9.3/aixtools/agents/context/processors/yaml.py +87 -0
  50. aixtools-0.9.3/aixtools/agents/context/reader.py +283 -0
  51. aixtools-0.9.3/aixtools/agents/history_compactor.py +341 -0
  52. aixtools-0.9.3/aixtools/auth/__init__.py +0 -0
  53. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/auth/auth.py +72 -6
  54. aixtools-0.9.3/aixtools/auth/user_store.py +64 -0
  55. aixtools-0.9.3/aixtools/auth_client/__init__.py +0 -0
  56. aixtools-0.9.3/aixtools/auth_client/client.py +153 -0
  57. aixtools-0.9.3/aixtools/auth_client/msal_client.py +28 -0
  58. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/compliance/private_data.py +3 -5
  59. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/context.py +2 -0
  60. aixtools-0.9.3/aixtools/evals/__init__.py +0 -0
  61. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/evals/run_evals.py +7 -0
  62. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/log_utils.py +1 -1
  63. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/log_objects.py +4 -3
  64. aixtools-0.9.3/aixtools/mcp/__init__.py +29 -0
  65. aixtools-0.9.3/aixtools/mcp/capabilities.py +130 -0
  66. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/client.py +1 -0
  67. aixtools-0.9.3/aixtools/mcp/middleware/__init__.py +9 -0
  68. aixtools-0.6.5/aixtools/mcp/middleware.py → aixtools-0.9.3/aixtools/mcp/middleware/error_handling.py +1 -3
  69. aixtools-0.9.3/aixtools/mcp/middleware/token_limit.py +375 -0
  70. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/server.py +36 -6
  71. aixtools-0.9.3/aixtools/mcp_direct/mcp/mcp_client.py +19 -0
  72. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/server/path.py +28 -2
  73. aixtools-0.9.3/aixtools/skills/__init__.py +0 -0
  74. aixtools-0.9.3/aixtools/skills/model.py +36 -0
  75. aixtools-0.9.3/aixtools/skills/prompt.py +39 -0
  76. aixtools-0.9.3/aixtools/skills/registry.py +199 -0
  77. aixtools-0.9.3/aixtools/skills/tools.py +105 -0
  78. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/testing/aix_test_model.py +47 -5
  79. aixtools-0.9.3/aixtools/testing/integration/__init__.py +0 -0
  80. aixtools-0.9.3/aixtools/testing/integration/a2a/__init__.py +0 -0
  81. aixtools-0.9.3/aixtools/testing/integration/a2a/executor.py +71 -0
  82. aixtools-0.9.3/aixtools/testing/integration/a2a/utils.py +43 -0
  83. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/__init__.py +16 -2
  84. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/config.py +95 -13
  85. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/config_util.py +26 -0
  86. aixtools-0.9.3/aixtools/utils/truncation.py +432 -0
  87. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/vault/vault.py +29 -6
  88. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools.egg-info/SOURCES.txt +58 -1
  89. {aixtools-0.6.5 → aixtools-0.9.3}/pyproject.toml +20 -1
  90. aixtools-0.6.5/aixtools/a2a/google_sdk/pydantic_ai_adapter/storage.py +0 -26
  91. aixtools-0.6.5/aixtools/mcp/__init__.py +0 -15
  92. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/config.toml +0 -0
  93. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/bn.json +0 -0
  94. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/en-US.json +0 -0
  95. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/gu.json +0 -0
  96. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/he-IL.json +0 -0
  97. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/hi.json +0 -0
  98. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/ja.json +0 -0
  99. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/kn.json +0 -0
  100. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/ml.json +0 -0
  101. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/mr.json +0 -0
  102. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/nl.json +0 -0
  103. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/ta.json +0 -0
  104. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/te.json +0 -0
  105. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/.chainlit/translations/zh-CN.json +0 -0
  106. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/__init__.py +0 -0
  107. {aixtools-0.6.5/aixtools/a2a/google_sdk → aixtools-0.9.3/aixtools/a2a}/__init__.py +0 -0
  108. {aixtools-0.6.5/aixtools/a2a/google_sdk/store → aixtools-0.9.3/aixtools/a2a/google_sdk}/__init__.py +0 -0
  109. {aixtools-0.6.5/aixtools/auth → aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter}/__init__.py +0 -0
  110. {aixtools-0.6.5/aixtools/evals → aixtools-0.9.3/aixtools/a2a/google_sdk/pydantic_ai_adapter/db}/__init__.py +0 -0
  111. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/store/alembic.ini +0 -0
  112. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/store/migrations/script.py.mako +0 -0
  113. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/google_sdk/store/migrations/versions/68c6975ed20b_added_a2a_sdk_task_table.py +0 -0
  114. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/a2a/utils.py +0 -0
  115. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/agent_batch.py +0 -0
  116. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/nodes_to_md.py +0 -0
  117. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/nodes_to_message.py +0 -0
  118. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/nodes_to_str.py +0 -0
  119. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/print_nodes.py +0 -0
  120. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/agents/prompt.py +0 -0
  121. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/app.py +0 -0
  122. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/chainlit.md +0 -0
  123. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/compliance/__init__.py +0 -0
  124. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/compliance/utils.py +0 -0
  125. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/db/__init__.py +0 -0
  126. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/db/database.py +0 -0
  127. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/db/vector_db.py +0 -0
  128. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/evals/__main__.py +0 -0
  129. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/evals/dataset.py +0 -0
  130. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/evals/discovery.py +0 -0
  131. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/google/client.py +0 -0
  132. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/__init__.py +0 -0
  133. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/app.py +0 -0
  134. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/display.py +0 -0
  135. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/export.py +0 -0
  136. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/filters.py +0 -0
  137. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/log_view/node_summary.py +0 -0
  138. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logfilters/__init__.py +0 -0
  139. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logfilters/context_filter.py +0 -0
  140. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/__init__.py +0 -0
  141. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/logging_config.py +0 -0
  142. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/mcp_log_models.py +0 -0
  143. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/mcp_logger.py +0 -0
  144. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/model_patch_logging.py +0 -0
  145. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/logging/open_telemetry.py +0 -0
  146. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/example_client.py +0 -0
  147. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/example_server.py +0 -0
  148. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/exceptions.py +0 -0
  149. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/fast_mcp_log.py +0 -0
  150. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/mcp/faulty_mcp.py +0 -0
  151. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/model_patch/model_patch.py +0 -0
  152. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/server/__init__.py +0 -0
  153. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/server/app_mounter.py +0 -0
  154. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/server/utils.py +0 -0
  155. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/testing/__init__.py +0 -0
  156. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/testing/agent_mock.py +0 -0
  157. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/testing/mock_tool.py +0 -0
  158. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/testing/model_patch_cache.py +0 -0
  159. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/tools/doctor/__init__.py +0 -0
  160. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/tools/doctor/mcp_tool_doctor.py +0 -0
  161. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/tools/doctor/tool_doctor.py +0 -0
  162. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/tools/doctor/tool_recommendation.py +0 -0
  163. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/chainlit/cl_agent_show.py +0 -0
  164. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/chainlit/cl_utils.py +0 -0
  165. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/enum_with_description.py +0 -0
  166. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/files.py +0 -0
  167. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/persisted_dict.py +0 -0
  168. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/utils/utils.py +0 -0
  169. {aixtools-0.6.5 → aixtools-0.9.3}/aixtools/vault/__init__.py +0 -0
  170. {aixtools-0.6.5 → aixtools-0.9.3}/setup.cfg +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aixtools
3
- Version: 0.6.5
3
+ Version: 0.9.3
4
4
  Summary: Tools for AI exploration and debugging
5
5
  Requires-Python: >=3.11.2
6
6
  Description-Content-Type: text/markdown
7
- Requires-Dist: a2a-sdk>=0.3.1
7
+ Requires-Dist: a2a-sdk[postgresql]>=0.3.3
8
8
  Requires-Dist: alembic>=1.17.1
9
9
  Requires-Dist: cachebox>=5.0.1
10
10
  Requires-Dist: chainlit>=2.5.5
@@ -13,12 +13,16 @@ Requires-Dist: fasta2a>=0.5.0
13
13
  Requires-Dist: fastmcp>=2.13.0
14
14
  Requires-Dist: hvac>=2.3.0
15
15
  Requires-Dist: ipykernel>=6.29.5
16
+ Requires-Dist: jupyterlab>=4.4.3
16
17
  Requires-Dist: langchain-chroma>=0.2.3
17
18
  Requires-Dist: langchain-ollama>=0.3.2
18
19
  Requires-Dist: langchain-openai>=0.3.14
19
20
  Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.3
20
21
  Requires-Dist: mcp>=1.20.0
22
+ Requires-Dist: msal>=1.29.0
23
+ Requires-Dist: msal-extensions>=1.1.0
21
24
  Requires-Dist: mypy>=1.18.2
25
+ Requires-Dist: nest_asyncio>=1.6.0
22
26
  Requires-Dist: pandas>=2.2.3
23
27
  Requires-Dist: psycopg2-binary>=2.9.11
24
28
  Requires-Dist: pydantic-evals>=0.4.10
@@ -30,7 +34,12 @@ Requires-Dist: ruff>=0.11.6
30
34
  Requires-Dist: sqlalchemy>=2.0.44
31
35
  Requires-Dist: streamlit>=1.44.1
32
36
  Requires-Dist: tiktoken>=0.9.0
37
+ Requires-Dist: openpyxl>=3.1.5
38
+ Requires-Dist: xlrd>=2.0.2
39
+ Requires-Dist: odfpy>=1.4.1
33
40
  Requires-Dist: watchdog>=6.0.0
41
+ Requires-Dist: python-frontmatter>=1.1.0
42
+ Requires-Dist: podkit>=0.4.0
34
43
  Provides-Extra: test
35
44
  Requires-Dist: pyyaml; extra == "test"
36
45
  Provides-Extra: feature
@@ -42,50 +51,48 @@ AIXtools is a comprehensive Python library for AI agent development, debugging,
42
51
 
43
52
  ## Capabilities
44
53
 
45
- Agents
46
- - Agent Development & Management - `aixtools/agents/`
47
- - Agent Batch Processing - `aixtools/agents/agent_batch.py`
48
- - Agent Prompting System - `aixtools/agents/prompt.py`
49
-
50
- A2A
51
- - Agent-to-Agent Communication (A2A) - `aixtools/a2a/`
52
- - Google SDK Integration for A2A - `aixtools/a2a/google_sdk/`
53
- - PydanticAI Adapter for Google SDK - `aixtools/a2a/google_sdk/pydantic_ai_adapter/`
54
-
55
- Logging & Debugging
56
- - Log Viewing Web Application - `log_view`
57
- - Object Logging System - `aixtools/logging/`
58
- - Model Patch Logging - `aixtools/logging/model_patch_logging.py`
59
- - Log Filtering System - `aixtools/logfilters/`
60
- - FastMCP Logging - `aixtools/mcp/fast_mcp_log.py`
61
- - MCP (Model Context Protocol) Support - `aixtools/logging/mcp_log_models.py`, `aixtools/logging/mcp_logger.py`
62
-
63
- Testing Tools & Evals
64
- - Evaluations - `aixtools/evals/` - Entry point: `evals`
65
- - Testing Utilities - `aixtools/testing/`
66
- - Mock Tool System - `aixtools/testing/mock_tool.py`
67
- - Model Patch Caching - `aixtools/testing/model_patch_cache.py`
68
- - Tool Doctor System - `aixtools/tools/doctor/`
69
- - Tool Recommendation Engine - `aixtools/tools/doctor/tool_recommendation.py`
70
- - FaultyMCP - `aixtools/mcp/faulty_mcp.py`
71
- - Agent Mock - `aixtools/testing/agent_mock.py`
72
-
73
- Databases
74
- - Database Integration - `aixtools/db/`
75
- - Vector Database Support - `aixtools/db/vector_db.py`
76
-
77
- Chainlit & HTTP Server
78
- - Chainlit Integration - `aixtools/app.py`, `aixtools/chainlit.md`
79
- - Chainlit Utilities - `aixtools/utils/chainlit/`
80
- - HTTP Server Framework - `aixtools/server/`
81
- - App Mounting System - `aixtools/server/app_mounter.py`
82
-
83
- Programming utils
84
- - Persisted Dictionary - `aixtools/utils/persisted_dict.py`
85
- - Enum with Description - `aixtools/utils/enum_with_description.py`
86
- - Context Management - `aixtools/context.py`
87
- - Configuration Management - `aixtools/utils/config.py`, `aixtools/utils/config_util.py`
88
- - File Utilities - `aixtools/utils/files.py`
54
+ - **[Installation](#installation)**
55
+ - **[Environment Configuration](#environment-configuration)**
56
+ - **[Agents](#agents)** - Core agent functionality
57
+ - Basic Agent Usage
58
+ - Agent Development & Management
59
+ - Agent Batch Processing
60
+ - Node Debugging and Visualization
61
+ - **[Context Engineering](#context-engineering)** - Transform files into agent-readable content
62
+ - File Type Processors
63
+ - Configuration
64
+ - Processing Examples
65
+ - **[Agent-to-Agent Communication](#a2a-agent-to-agent-communication)** - Inter-agent communication framework
66
+ - Core Features
67
+ - Google SDK Integration
68
+ - Remote Agent Connections
69
+ - **[Testing & Tools](#testing--tools)** - Comprehensive testing utilities
70
+ - Running Tests
71
+ - Testing Utilities
72
+ - Mock Tool System
73
+ - Model Patch Caching
74
+ - Agent Mock
75
+ - FaultyMCP Testing Server
76
+ - MCP Tool Doctor
77
+ - Tool Doctor
78
+ - Evaluations
79
+ - **[Logging & Debugging](#logging--debugging)** - Advanced logging and debugging
80
+ - Basic Logging
81
+ - Log Viewing Application
82
+ - Object Logging
83
+ - MCP Logging
84
+ - **[Databases](#databases)** - Traditional and vector database support
85
+ - **[Chainlit & HTTP Server](#chainlit--http-server)** - Web interfaces and server framework
86
+ - Chainlit Integration
87
+ - HTTP Server Framework
88
+ - **[Programming Utilities](#programming-utilities)** - Essential utilities
89
+ - Persisted Dictionary
90
+ - Enum with Description
91
+ - Context Management
92
+ - Configuration Management
93
+ - File Utilities
94
+ - Chainlit Utilities
95
+ - Truncation Utilities
89
96
 
90
97
  ## Installation
91
98
 
@@ -101,11 +108,12 @@ uv add --upgrade aixtools
101
108
 
102
109
  ## Environment Configuration
103
110
 
104
- AIXtools requires environment variables for model providers.
111
+ AIXtools requires environment variables for model providers.
105
112
 
106
- **IMPORTANT:** Create a `.env` file based on [`.env_template`](./.env_template):
113
+ **IMPORTANT:** Create a `.env` file based on `.env_template`:
107
114
 
108
115
  Here is an example configuration:
116
+
109
117
  ```bash
110
118
  # Model family (azure, openai, or ollama)
111
119
  MODEL_FAMILY=azure
@@ -155,7 +163,7 @@ result, nodes = await run_agent(agent, "Tell me about AI")
155
163
 
156
164
  ### Node Debugging and Visualization
157
165
 
158
- The [`print_nodes`](aixtools/agents/print_nodes.py) module provides a clean, indented output for easy reading of the node from agent execution.
166
+ The `print_nodes` module provides a clean, indented output for easy reading of the node from agent execution.
159
167
 
160
168
  ```python
161
169
  from aixtools.agents.print_nodes import print_nodes, print_node
@@ -168,11 +176,11 @@ print_nodes(nodes)
168
176
  ```
169
177
 
170
178
  **Features:**
171
- - **Node Type Detection**: Automatically handles different node types (`UserPromptNode`, `CallToolsNode`, `ModelRequestNode`, `End`)
172
- - **Formatted Output**: Provides clean, indented output for easy reading
173
- - **Tool Call Visualization**: Shows tool names and arguments for tool calls
174
- - **Text Content Display**: Formats text parts with proper indentation
175
- - **Model Request Summary**: Shows character count for model requests to avoid verbose output
179
+ - Node Type Detection: Automatically handles different node types (`UserPromptNode`, `CallToolsNode`, `ModelRequestNode`, `End`)
180
+ - Formatted Output: Provides clean, indented output for easy reading
181
+ - Tool Call Visualization: Shows tool names and arguments for tool calls
182
+ - Text Content Display: Formats text parts with proper indentation
183
+ - Model Request Summary: Shows character count for model requests to avoid verbose output
176
184
 
177
185
  **Node Types Supported:**
178
186
  - `UserPromptNode` - Displays user prompts with indentation
@@ -198,14 +206,190 @@ async for result in agent_batch(query_parameters):
198
206
  print(result)
199
207
  ```
200
208
 
209
+ ## Context Engineering
210
+
211
+ Transform file formats into agent-readable content with enforced size limits to prevent context overflow. The main entry point is the `read_file()` function in `aixtools/agents/context/reader.py`, which provides automatic file type detection and delegates to specialized processors for each file type.
212
+
213
+ ### Basic Usage
214
+
215
+ The `read_file()` function in `reader.py` is the main interface for processing files. It automatically detects file types and applies appropriate truncation strategies.
216
+
217
+ ```python
218
+ from aixtools.agents.context.reader import read_file
219
+ from pathlib import Path
220
+
221
+ # Read a file with automatic type detection and truncation
222
+ result = read_file(Path("data.csv"))
223
+
224
+ if result.success:
225
+ print(f"File type: {result.file_type}")
226
+ print(f"Content length: {len(result.content)}")
227
+ print(f"Truncation info: {result.truncation_info}")
228
+ print(result.content)
229
+
230
+ # Optionally specify custom tokenizer and limits
231
+ result = read_file(
232
+ Path("large_file.json"),
233
+ max_tokens_per_file=10000,
234
+ max_total_output=100000
235
+ )
236
+ ```
237
+
238
+ ### Architecture
239
+
240
+ The context engineering system is organized with `reader.py` as the main interface:
241
+ - `reader.py` - Main `read_file()` function with file type detection and processing coordination
242
+ - `config.py` - Configurable size limits and thresholds
243
+ - `processors/` - Specialized processors for each file type (text, code, JSON, CSV, PDF, etc.)
244
+ - `data_models.py` - Data classes for results and metadata
245
+
246
+ ### Supported File Types
247
+
248
+ - Text files (`.txt`, `.log`, `.md`)
249
+ - Code files (Python, JavaScript, etc.)
250
+ - Structured data (`JSON`, `YAML`, `XML`)
251
+ - Tabular data (`CSV`, `TSV`)
252
+ - Documents (`PDF`, `DOCX`)
253
+ - Spreadsheets (`.xlsx`, `.xls`, `.ods`)
254
+ - Images (`PNG`, `JPEG`, `GIF`, `WEBP`)
255
+ - Audio files
256
+
257
+ ### Key Features
258
+
259
+ - Automatic file type detection based on MIME types and extensions
260
+ - Token-based truncation with configurable limits per file
261
+ - Intelligent content sampling (head + tail rows for tabular data)
262
+ - Structure-aware truncation for `JSON`, `YAML`, and `XML`
263
+ - Markdown conversion for documents using `markitdown`
264
+ - Binary content support for images with metadata extraction
265
+ - Comprehensive error handling with partial results when possible
266
+
267
+ ### Configuration
268
+
269
+ All limits are configurable via environment variables:
270
+
271
+ ```bash
272
+ # Output limits
273
+ MAX_TOKENS_PER_FILE=5000
274
+ MAX_TOTAL_OUTPUT=50000
275
+
276
+ # Text truncation
277
+ MAX_LINES=200
278
+ MAX_LINE_LENGTH=1000
279
+
280
+ # Tabular truncation
281
+ MAX_COLUMNS=50
282
+ DEFAULT_ROWS_HEAD=20
283
+ DEFAULT_ROWS_MIDDLE=10
284
+ DEFAULT_ROWS_TAIL=10
285
+ MAX_CELL_LENGTH=500
286
+
287
+ # Images
288
+ MAX_IMAGE_ATTACHMENT_SIZE=2097152 # 2MB
289
+ ```
290
+
291
+ ### Processing Examples
292
+
293
+ The recommended approach is to use the `read_file()` function which automatically handles file type detection and processing. However, you can also use individual processors directly for specific file types.
294
+
295
+ #### Using read_file() (Recommended)
296
+
297
+ ```python
298
+ from aixtools.agents.context.reader import read_file
299
+ from pathlib import Path
300
+
301
+ # Process any file type automatically
302
+ result = read_file(Path("data.csv"))
303
+ if result.success:
304
+ print(result.content)
305
+
306
+ # Works with all supported types
307
+ pdf_result = read_file(Path("report.pdf"))
308
+ excel_result = read_file(Path("workbook.xlsx"))
309
+ json_result = read_file(Path("config.json"))
310
+ ```
311
+
312
+ #### Processing Tabular Data Directly
313
+
314
+ ```python
315
+ from aixtools.agents.context.processors.tabular import process_tabular
316
+ from pathlib import Path
317
+
318
+ # Process specific row range from large CSV
319
+ result = process_tabular(
320
+ file_path=Path("large_data.csv"),
321
+ start_row=100,
322
+ end_row=200,
323
+ max_columns=20,
324
+ max_cell_length=500
325
+ )
326
+
327
+ print(f"Rows shown: {result.truncation_info.rows_shown}")
328
+ print(f"Columns shown: {result.truncation_info.columns_shown}")
329
+ ```
330
+
331
+ #### Processing Spreadsheets Directly
332
+
333
+ ```python
334
+ from aixtools.agents.context.processors.spreadsheet import process_spreadsheet
335
+ from pathlib import Path
336
+
337
+ # Process Excel file with multiple sheets
338
+ result = process_spreadsheet(
339
+ file_path=Path("workbook.xlsx"),
340
+ max_sheets=3,
341
+ max_rows_per_sheet_head=20,
342
+ max_rows_per_sheet_tail=10
343
+ )
344
+
345
+ # Content includes all processed sheets with truncation info
346
+ print(result.content)
347
+ ```
348
+
349
+ #### Processing Documents Directly
350
+
351
+ ```python
352
+ from aixtools.agents.context.processors.document import process_document
353
+ from pathlib import Path
354
+
355
+ # Convert PDF to markdown and truncate
356
+ result = process_document(
357
+ file_path=Path("report.pdf"),
358
+ max_lines=200,
359
+ max_line_length=1000
360
+ )
361
+
362
+ if result.was_extracted:
363
+ print("Document successfully converted to markdown")
364
+ print(result.content)
365
+ ```
366
+
367
+ ### Output Format
368
+
369
+ All processors return consistent output with metadata:
370
+
371
+ ```
372
+ File: data.csv
373
+ Columns: 8 (of 20000 total)
374
+ Rows: 20 (of 1000000 total)
375
+
376
+ col1,col2,...,col8
377
+ value1,value2,...
378
+ ...
379
+
380
+ Truncated: columns: 8 of 20000, rows: 20 of 1000000, 45 cells
381
+ ```
382
+
383
+ The context engineering system ensures agents receive properly formatted, size-limited content that fits within token budgets while preserving the most relevant information from each file type.
384
+
201
385
  ## A2A (Agent-to-Agent Communication)
202
386
 
203
- The A2A module provides a comprehensive framework for enabling sophisticated communication between AI agents across different environments and platforms. It includes Google SDK integration, PydanticAI adapters, and FastA2A application conversion capabilities.
387
+ The `A2A` module provides a comprehensive framework for enabling sophisticated communication between AI agents across different environments and platforms. It includes Google SDK integration, `PydanticAI` adapters, and `FastA2A` application conversion capabilities.
204
388
 
205
389
  ### Core Features
206
390
 
207
391
  **Agent Application Conversion**
208
- - Convert PydanticAI agents into FastA2A applications (deprecated)
392
+ - Convert `PydanticAI` agents into `FastA2A` applications (deprecated)
209
393
  - Support for session metadata extraction and context management
210
394
  - Custom worker classes with enhanced data part support
211
395
  - Automatic handling of user and session identification
@@ -219,12 +403,12 @@ The A2A module provides a comprehensive framework for enabling sophisticated com
219
403
  **Google SDK Integration**
220
404
  - Native integration with Google's A2A SDK
221
405
  - Card-based agent representation and discovery
222
- - PydanticAI adapter for seamless Google SDK compatibility
406
+ - `PydanticAI` adapter for seamless Google SDK compatibility
223
407
  - Storage and execution management for agent interactions
224
408
 
225
- ### Agent-to-Agent Communication (A2A)
409
+ ### Basic Usage
226
410
 
227
- Enable sophisticated agent interactions with Google SDK integration and PydanticAI adapters.
411
+ Enable sophisticated agent interactions with Google SDK integration and `PydanticAI` adapters.
228
412
 
229
413
  ```python
230
414
  from aixtools.a2a.google_sdk.remote_agent_connection import RemoteAgentConnection
@@ -344,7 +528,7 @@ from aixtools.agents.agent import get_agent, run_agent
344
528
  async def main():
345
529
  # Create an agent
346
530
  agent = get_agent(system_prompt="You are a helpful assistant.")
347
-
531
+
348
532
  # Run agent - logging is automatic via ObjectLogger
349
533
  result, nodes = await run_agent(
350
534
  agent,
@@ -352,19 +536,19 @@ async def main():
352
536
  debug=True, # Enable debug logging
353
537
  log_model_requests=True # Log model requests/responses
354
538
  )
355
-
539
+
356
540
  print(f"Result: {result}")
357
541
  print(f"Logged {len(nodes)} nodes")
358
542
  ```
359
543
 
360
544
  ### Log Viewing Application
361
545
 
362
- Interactive Streamlit application for analyzing logged objects and debugging agent behavior.
546
+ Interactive `Streamlit` application for analyzing logged objects and debugging agent behavior.
363
547
 
364
548
  **Features:**
365
549
  - Log file selection and filtering
366
550
  - Node visualization with expand/collapse
367
- - Export capabilities to JSON
551
+ - Export capabilities to `JSON`
368
552
  - Regex pattern matching
369
553
  - Real-time log monitoring
370
554
 
@@ -389,15 +573,15 @@ with ObjectLogger() as logger:
389
573
  logger.log(agent_response)
390
574
  ```
391
575
 
392
- ### MCP logging
576
+ ### MCP Logging
393
577
 
394
- AIXtools provides MCP support for both client and server implementations with easier logging for debugging pourposes.
578
+ AIXtools provides MCP support for both client and server implementations with easier logging for debugging purposes.
395
579
 
396
- **Example:**
580
+ **Example:**
397
581
 
398
582
  Let's assume we have an MCP server that runs an agent tool.
399
583
 
400
- Note that the `ctx: Context` parameter is passed to `run_agent`, this will enable logging to the MCP client.
584
+ Note that the `ctx: Context` parameter is passed to `run_agent()`, this will enable logging to the MCP client.
401
585
 
402
586
  ```python
403
587
  @mcp.tool
@@ -409,7 +593,7 @@ async def my_tool_with_agent(query: str, ctx: Context) -> str:
409
593
  return str(ret)
410
594
  ```
411
595
 
412
- On the client side, you can create an agent connected to the MCP server, the "nodes" from the MCP server will show on the STDOUT so you can see what's going on the MCP server's agent loop
596
+ On the client side, you can create an agent connected to the MCP server, the nodes from the MCP server will show on the `STDOUT` so you can see what's going on the MCP server's agent loop.
413
597
 
414
598
  ```python
415
599
  mcp = get_mcp_client("http://localhost:8000") # Get an MCP client with a default log handler that prints to STDOUT
@@ -430,6 +614,84 @@ from aixtools.mcp.fast_mcp_log import FastMcpLog
430
614
  mcp = FastMcpLog("Demo")
431
615
  ```
432
616
 
617
+ ## Testing & Tools
618
+
619
+ AIXtools provides comprehensive testing utilities and diagnostic tools for AI agent development and debugging.
620
+
621
+ ### Running Tests
622
+
623
+ Execute the test suite using the provided scripts:
624
+
625
+ ```bash
626
+ # Run all tests
627
+ ./scripts/test.sh
628
+
629
+ # Run unit tests only
630
+ ./scripts/test_unit.sh
631
+
632
+ # Run integration tests only
633
+ ./scripts/test_integration.sh
634
+ ```
635
+
636
+ ### Testing Utilities
637
+
638
+ The testing module provides mock tools, model patching, and test utilities for comprehensive agent testing.
639
+
640
+ ```python
641
+ from aixtools.testing.mock_tool import MockTool
642
+ from aixtools.testing.model_patch_cache import ModelPatchCache
643
+ from aixtools.testing.aix_test_model import AixTestModel
644
+
645
+ # Create mock tools for testing
646
+ mock_tool = MockTool(name="test_tool", response="mock response")
647
+
648
+ # Use model patch caching for consistent test results
649
+ cache = ModelPatchCache()
650
+ cached_response = cache.get_cached_response("test_prompt")
651
+
652
+ # Test model for controlled testing scenarios
653
+ test_model = AixTestModel()
654
+ ```
655
+
656
+ ### Mock Tool System
657
+
658
+ Create and manage mock tools for testing agent behavior without external dependencies.
659
+
660
+ ```python
661
+ from aixtools.testing.mock_tool import MockTool
662
+
663
+ # Create a mock tool with predefined responses
664
+ mock_calculator = MockTool(
665
+ name="calculator",
666
+ description="Performs mathematical calculations",
667
+ response_map={
668
+ "2+2": "4",
669
+ "10*5": "50"
670
+ }
671
+ )
672
+
673
+ # Use in agent testing
674
+ agent = get_agent(tools=[mock_calculator])
675
+ result = await run_agent(agent, "What is 2+2?")
676
+ ```
677
+
678
+ ### Model Patch Caching
679
+
680
+ Cache model responses for consistent testing and development workflows.
681
+
682
+ ```python
683
+ from aixtools.testing.model_patch_cache import ModelPatchCache
684
+
685
+ # Initialize cache
686
+ cache = ModelPatchCache(cache_dir="./test_cache")
687
+
688
+ # Cache responses for specific prompts
689
+ cache.cache_response("test prompt", "cached response")
690
+
691
+ # Retrieve cached responses
692
+ response = cache.get_cached_response("test prompt")
693
+ ```
694
+
433
695
  ### Model Patching System
434
696
 
435
697
  Dynamic model behavior modification for testing and debugging.
@@ -443,16 +705,39 @@ with ModelPatch() as patch:
443
705
  result = await agent.run("test prompt")
444
706
  ```
445
707
 
446
- ### FaultyMCP
708
+ ### Agent Mock
709
+
710
+ Replay previously recorded agent runs without executing the actual agent. Useful for testing, debugging, and creating reproducible test cases.
711
+
712
+ ```python
713
+ from aixtools.testing.agent_mock import AgentMock
714
+ from aixtools.agents.agent import get_agent, run_agent
715
+
716
+ # Run an agent and capture its execution
717
+ agent = get_agent(system_prompt="You are a helpful assistant.")
718
+ result, nodes = await run_agent(agent, "Explain quantum computing")
719
+
720
+ # Create a mock agent from the recorded nodes
721
+ agent_mock = AgentMock(nodes=nodes, result_output=result)
722
+
723
+ # Save the mock for later use
724
+ agent_mock.save(Path("test_data/quantum_mock.pkl"))
725
+
726
+ # Load and replay the mock agent
727
+ loaded_mock = AgentMock.load(Path("test_data/quantum_mock.pkl"))
728
+ result, nodes = await run_agent(loaded_mock, "any prompt") # Returns recorded nodes
729
+ ```
730
+
731
+ ### FaultyMCP Testing Server
447
732
 
448
- A specialized MCP server designed for testing error handling and resilience in MCP client implementations. FaultyMCP simulates various failure scenarios including network errors, server crashes, and random exceptions.
733
+ A specialized MCP server designed for testing error handling and resilience in MCP client implementations. `FaultyMCP` simulates various failure scenarios including network errors, server crashes, and random exceptions.
449
734
 
450
735
  **Features:**
451
736
  - Configurable error probabilities for different request types
452
- - HTTP 404 error injection for POST/DELETE requests
453
- - Server crash simulation on GET requests
737
+ - HTTP 404 error injection for `POST`/`DELETE` requests
738
+ - Server crash simulation on `GET` requests
454
739
  - Random exception throwing in tool operations
455
- - MCP-specific error simulation (ValidationError, ResourceError, etc.)
740
+ - MCP-specific error simulation (`ValidationError`, `ResourceError`, etc.)
456
741
  - Safe mode for controlled testing
457
742
 
458
743
  ```python
@@ -468,6 +753,7 @@ run_server_on_port()
468
753
  ```
469
754
 
470
755
  **Command Line Usage:**
756
+
471
757
  ```bash
472
758
  # Run with default error probabilities
473
759
  python -m aixtools.mcp.faulty_mcp
@@ -483,17 +769,72 @@ python -m aixtools.mcp.faulty_mcp \
483
769
  --prob-in-list-tools-throw 0.3
484
770
  ```
485
771
 
486
- By default, the "FaultyMCP" includes several tools you can use in your tests:
487
- - `add(a, b)` - Basic addition (reliable)
488
- - `multiply(a, b)` - Basic multiplication (reliable)
772
+ **Available Test Tools:**
773
+ - `add(a, b)` - Reliable addition operation
774
+ - `multiply(a, b)` - Reliable multiplication operation
489
775
  - `always_error()` - Always throws an exception
490
776
  - `random_throw_exception(a, b, prob)` - Randomly throws exceptions
491
777
  - `freeze_server(seconds)` - Simulates server freeze
492
778
  - `throw_404_exception()` - Throws HTTP 404 error
493
779
 
494
- ### Evals
780
+ ### MCP Tool Doctor
495
781
 
496
- Run comprehensive Agent/LLM evaluations using the built-in evaluation discovery based on Pydantic-AI framework with AIXtools enhancements.
782
+ Analyze tools from MCP (Model Context Protocol) servers and receive AI-powered recommendations for improvement.
783
+
784
+ ```python
785
+ from aixtools.tools.doctor.mcp_tool_doctor import tool_doctor_mcp
786
+ from pydantic_ai.mcp import MCPServerStreamableHTTP, MCPServerStdio
787
+
788
+ # Analyze HTTP MCP server
789
+ recommendations = await tool_doctor_mcp(mcp_url='http://127.0.0.1:8000/mcp')
790
+ for rec in recommendations:
791
+ print(rec)
792
+
793
+ # Analyze STDIO MCP server
794
+ server = MCPServerStdio(command='fastmcp', args=['run', 'my_server.py'])
795
+ recommendations = await tool_doctor_mcp(mcp_server=server, verbose=True)
796
+ ```
797
+
798
+ **Command Line Usage:**
799
+
800
+ ```bash
801
+ # Analyze HTTP MCP server (default)
802
+ tool_doctor_mcp
803
+
804
+ # Analyze specific HTTP MCP server
805
+ tool_doctor_mcp --mcp-url http://localhost:9000/mcp --verbose
806
+
807
+ # Analyze STDIO MCP server
808
+ tool_doctor_mcp --stdio-command fastmcp --stdio-args run my_server.py --debug
809
+ ```
810
+
811
+ **Available options:**
812
+ - `--mcp-url URL` - URL of HTTP MCP server (default: `http://127.0.0.1:8000/mcp`)
813
+ - `--stdio-command CMD` - Command to run STDIO MCP server
814
+ - `--stdio-args ARGS` - Arguments for STDIO MCP server command
815
+ - `--verbose` - Enable verbose output
816
+ - `--debug` - Enable debug output
817
+
818
+ ### Tool Doctor
819
+
820
+ Analyze tool usage patterns from agent logs and get optimization recommendations.
821
+
822
+ ```python
823
+ from aixtools.tools.doctor.tool_doctor import ToolDoctor
824
+ from aixtools.tools.doctor.tool_recommendation import ToolRecommendation
825
+
826
+ # Analyze tool usage patterns
827
+ doctor = ToolDoctor()
828
+ analysis = doctor.analyze_tools(agent_logs)
829
+
830
+ # Get tool recommendations
831
+ recommendation = ToolRecommendation()
832
+ suggestions = recommendation.recommend_tools(agent_context)
833
+ ```
834
+
835
+ ### Evaluations
836
+
837
+ Run comprehensive Agent/LLM evaluations using the built-in evaluation discovery based on `Pydantic-AI` framework with AIXtools enhancements.
497
838
 
498
839
  ```bash
499
840
  # Run all evaluations
@@ -513,16 +854,16 @@ python -m aixtools.evals --min-assertions 0.8
513
854
  ```
514
855
 
515
856
  **Command Line Options:**
516
- - `--evals-dir` - Directory containing eval_*.py files (default: evals)
857
+ - `--evals-dir` - Directory containing `eval_*.py` files (default: `evals`)
517
858
  - `--filter` - Filter to run only matching evaluations
518
- - `--include-input` - Include input in report output (default: True)
519
- - `--include-output` - Include output in report output (default: True)
859
+ - `--include-input` - Include input in report output (default: `True`)
860
+ - `--include-output` - Include output in report output (default: `True`)
520
861
  - `--include-evaluator-failures` - Include evaluator failures in report
521
862
  - `--include-reasons` - Include reasons in report output
522
- - `--min-assertions` - Minimum assertions average required for success (default: 1.0)
863
+ - `--min-assertions` - Minimum assertions average required for success (default: `1.0`)
523
864
  - `--verbose` - Print detailed information about discovery and processing
524
865
 
525
- The evaluation system discovers and runs all Dataset objects from eval_*.py files in the specified directory, similar to test runners but specifically designed for LLM evaluations using pydantic_evals.
866
+ The evaluation system discovers and runs all `Dataset` objects from `eval_*.py` files in the specified directory, similar to test runners but specifically designed for LLM evaluations using `pydantic_evals`.
526
867
 
527
868
  **Discovery Mechanism**
528
869
 
@@ -536,6 +877,7 @@ The evaluation framework uses an automatic discovery system:
536
877
  5. **Filtering**: Supports filtering by module name, file name, dataset name, or fully qualified name
537
878
 
538
879
  **Example Evaluation File Structure:**
880
+
539
881
  ```python
540
882
  # eval_math_operations.py
541
883
  from pydantic_evals import Dataset, Case
@@ -564,7 +906,7 @@ def evaluator_check_output(ctx: EvaluatorContext) -> bool:
564
906
  ```
565
907
 
566
908
  The discovery system will:
567
- - Find `eval_math_operations.py` in the evals directory
909
+ - Find `eval_math_operations.py` in the `evals` directory
568
910
  - Discover `dataset_addition` as an evaluation dataset
569
911
  - Use `evaluate_math_agent` as the target function for evaluation
570
912
  - Run each case through the target function and evaluate results
@@ -574,237 +916,67 @@ The discovery system will:
574
916
  The evaluation system uses name-based discovery for all components:
575
917
 
576
918
  **Target Functions** (exactly one required per eval file):
577
- - **Purpose**: The main function being evaluated - processes inputs and returns outputs
578
- - **Naming**: Functions named `target_*` (e.g., `target_my_function`)
579
- - **Signature**: `def target_name(inputs: InputType) -> OutputType` or `async def target_name(inputs: InputType) -> OutputType`
580
- - **Example**: `async def target_math_agent(input_text: str) -> str`
919
+ - Purpose: The main function being evaluated - processes inputs and returns outputs
920
+ - Naming: Functions named `target_*` (e.g., `target_my_function`)
921
+ - Signature: `def target_name(inputs: InputType) -> OutputType` or `async def target_name(inputs: InputType) -> OutputType`
922
+ - Example: `async def target_math_agent(input_text: str) -> str`
581
923
 
582
924
  **Scoring Functions** (optional):
583
- - **Purpose**: Determine if evaluation results meet success criteria
584
- - **Naming**: Functions named `scorer_*` (e.g., `scorer_custom`)
585
- - **Signature**: `def scorer_name(report: EvaluationReport, dataset: AixDataset, min_score: float = 1.0, verbose: bool = False) -> bool`
586
- - **Example**: `def scorer_accuracy_threshold(report, dataset, min_score=0.8, verbose=False) -> bool`
925
+ - Purpose: Determine if evaluation results meet success criteria
926
+ - Naming: Functions named `scorer_*` (e.g., `scorer_custom`)
927
+ - Signature: `def scorer_name(report: EvaluationReport, dataset: AixDataset, min_score: float = 1.0, verbose: bool = False) -> bool`
928
+ - Example: `def scorer_accuracy_threshold(report, dataset, min_score=0.8, verbose=False) -> bool`
587
929
 
588
930
  **Evaluator Functions** (optional):
589
- - **Purpose**: Custom evaluation logic for comparing outputs with expected results
590
- - **Naming**: Functions named `evaluator_*` (e.g., `evaluator_check_output`)
591
- - **Signature**: `def evaluator_name(ctx: EvaluatorContext) -> EvaluatorOutput` or `async def evaluator_name(ctx: EvaluatorContext) -> EvaluatorOutput`
592
- - **Example**: `def evaluator_exact_match(ctx) -> EvaluatorOutput`
931
+ - Purpose: Custom evaluation logic for comparing outputs with expected results
932
+ - Naming: Functions named `evaluator_*` (e.g., `evaluator_check_output`)
933
+ - Signature: `def evaluator_name(ctx: EvaluatorContext) -> EvaluatorOutput` or `async def evaluator_name(ctx: EvaluatorContext) -> EvaluatorOutput`
934
+ - Example: `def evaluator_exact_match(ctx) -> EvaluatorOutput`
593
935
 
594
936
  This name-based approach works seamlessly with both synchronous and asynchronous functions.
595
937
 
596
938
  #### Scoring System
597
939
 
598
- The framework includes a custom scoring system with [`average_assertions`](aixtools/evals/dataset.py:67) as the default scorer. This scorer checks if the average assertion score meets a minimum threshold and provides detailed pass/fail reporting.
599
-
600
- ## Testing & Tools
601
-
602
- AIXtools provides comprehensive testing utilities and diagnostic tools for AI agent development and debugging.
603
-
604
- ### Running Tests
605
-
606
- Execute the test suite using the provided scripts:
607
-
608
- ```bash
609
- # Run all tests
610
- ./scripts/test.sh
611
-
612
- # Run unit tests only
613
- ./scripts/test_unit.sh
614
-
615
- # Run integration tests only
616
- ./scripts/test_integration.sh
617
- ```
618
-
619
- ### Testing Utilities
620
-
621
- The testing module provides mock tools, model patching, and test utilities for comprehensive agent testing.
622
-
623
- ```python
624
- from aixtools.testing.mock_tool import MockTool
625
- from aixtools.testing.model_patch_cache import ModelPatchCache
626
- from aixtools.testing.aix_test_model import AixTestModel
627
-
628
- # Create mock tools for testing
629
- mock_tool = MockTool(name="test_tool", response="mock response")
630
-
631
- # Use model patch caching for consistent test results
632
- cache = ModelPatchCache()
633
- cached_response = cache.get_cached_response("test_prompt")
634
-
635
- # Test model for controlled testing scenarios
636
- test_model = AixTestModel()
637
- ```
638
-
639
- #### MCP Tool Doctor
640
-
641
- Analyze tools from MCP (Model Context Protocol) servers and receive AI-powered recommendations for improvement.
642
-
643
- ```python
644
- from aixtools.tools.doctor.mcp_tool_doctor import tool_doctor_mcp
645
- from pydantic_ai.mcp import MCPServerStreamableHTTP, MCPServerStdio
646
-
647
- # Analyze HTTP MCP server
648
- recommendations = await tool_doctor_mcp(mcp_url='http://127.0.0.1:8000/mcp')
649
- for rec in recommendations:
650
- print(rec)
651
-
652
- # Analyze STDIO MCP server
653
- server = MCPServerStdio(command='fastmcp', args=['run', 'my_server.py'])
654
- recommendations = await tool_doctor_mcp(mcp_server=server, verbose=True)
655
- ```
656
-
657
- **Command Line Usage:**
658
-
659
- ```bash
660
- # Analyze HTTP MCP server (default)
661
- tool_doctor_mcp
662
-
663
- # Analyze specific HTTP MCP server
664
- tool_doctor_mcp --mcp-url http://localhost:9000/mcp --verbose
665
-
666
- # Analyze STDIO MCP server
667
- tool_doctor_mcp --stdio-command fastmcp --stdio-args run my_server.py --debug
668
-
669
- # Available options:
670
- # --mcp-url URL URL of HTTP MCP server (default: http://127.0.0.1:8000/mcp)
671
- # --stdio-command CMD Command to run STDIO MCP server
672
- # --stdio-args ARGS Arguments for STDIO MCP server command
673
- # --verbose Enable verbose output
674
- # --debug Enable debug output
675
- ```
676
-
677
- #### Tool Doctor
678
-
679
- Analyze tool usage patterns from agent logs and get optimization recommendations.
680
-
681
- ```python
682
- from aixtools.tools.doctor.tool_doctor import ToolDoctor
683
- from aixtools.tools.doctor.tool_recommendation import ToolRecommendation
684
-
685
- # Analyze tool usage patterns
686
- doctor = ToolDoctor()
687
- analysis = doctor.analyze_tools(agent_logs)
688
-
689
- # Get tool recommendations
690
- recommendation = ToolRecommendation()
691
- suggestions = recommendation.recommend_tools(agent_context)
692
- ```
693
-
694
- ### Mock Tool System
695
-
696
- Create and manage mock tools for testing agent behavior without external dependencies.
697
-
698
- ```python
699
- from aixtools.testing.mock_tool import MockTool
700
-
701
- # Create a mock tool with predefined responses
702
- mock_calculator = MockTool(
703
- name="calculator",
704
- description="Performs mathematical calculations",
705
- response_map={
706
- "2+2": "4",
707
- "10*5": "50"
708
- }
709
- )
710
-
711
- # Use in agent testing
712
- agent = get_agent(tools=[mock_calculator])
713
- result = await run_agent(agent, "What is 2+2?")
714
- ```
940
+ The framework includes a custom scoring system with `average_assertions` as the default scorer. This scorer checks if the average assertion score meets a minimum threshold and provides detailed pass/fail reporting.
715
941
 
716
- ### Model Patch Caching
717
-
718
- Cache model responses for consistent testing and development workflows.
719
-
720
- ```python
721
- from aixtools.testing.model_patch_cache import ModelPatchCache
722
-
723
- # Initialize cache
724
- cache = ModelPatchCache(cache_dir="./test_cache")
725
-
726
- # Cache responses for specific prompts
727
- cache.cache_response("test prompt", "cached response")
728
-
729
- # Retrieve cached responses
730
- response = cache.get_cached_response("test prompt")
731
- ```
942
+ ## Chainlit & HTTP Server
732
943
 
733
- ### FaultyMCP Testing Server
944
+ ### Chainlit Integration
734
945
 
735
- Specialized MCP server for testing error handling and resilience in MCP implementations.
946
+ Ready-to-use `Chainlit` application for interactive agent interfaces.
736
947
 
737
948
  ```python
738
- from aixtools.mcp.faulty_mcp import run_server_on_port, config
739
-
740
- # Configure error probabilities for testing
741
- config.prob_on_post_404 = 0.3 # 30% chance of 404 on POST
742
- config.prob_on_get_crash = 0.1 # 10% chance of crash on GET
743
- config.prob_in_list_tools_throw = 0.2 # 20% chance of exception
744
-
745
- # Run the faulty server for testing
746
- run_server_on_port(port=8888)
747
- ```
748
-
749
- **Available Test Tools:**
750
- - `add(a, b)` - Reliable addition operation
751
- - `multiply(a, b)` - Reliable multiplication operation
752
- - `always_error()` - Always throws an exception
753
- - `random_throw_exception(a, b, prob)` - Randomly throws exceptions
754
- - `freeze_server(seconds)` - Simulates server freeze
755
- - `throw_404_exception()` - Throws HTTP 404 error
756
-
757
- **Command Line Usage:**
758
- ```bash
759
- # Run with default error probabilities
760
- python -m aixtools.mcp.faulty_mcp
761
-
762
- # Run in safe mode (no errors)
763
- python -m aixtools.mcp.faulty_mcp --safe-mode
764
-
765
- # Custom configuration
766
- python -m aixtools.mcp.faulty_mcp \
767
- --port 8888 \
768
- --prob-on-post-404 0.2 \
769
- --prob-on-get-crash 0.1
949
+ # Run the Chainlit app
950
+ # Configuration in aixtools/chainlit.md
951
+ # Main app in aixtools/app.py
770
952
  ```
771
953
 
772
- ### Agent Mock
954
+ ### HTTP Server Framework
773
955
 
774
- Replay previously recorded agent runs without executing the actual agent. Useful for testing, debugging, and creating reproducible test cases.
956
+ AIXtools provides an HTTP server framework for deploying agents and tools as web services.
775
957
 
776
958
  ```python
777
- from aixtools.testing.agent_mock import AgentMock
778
- from aixtools.agents.agent import get_agent, run_agent
959
+ from aixtools.server.app_mounter import mount_app
960
+ from aixtools.server import create_server
779
961
 
780
- # Run an agent and capture its execution
781
- agent = get_agent(system_prompt="You are a helpful assistant.")
782
- result, nodes = await run_agent(agent, "Explain quantum computing")
962
+ # Create and configure server
963
+ server = create_server()
783
964
 
784
- # Create a mock agent from the recorded nodes
785
- agent_mock = AgentMock(nodes=nodes, result_output=result)
786
-
787
- # Save the mock for later use
788
- agent_mock.save(Path("test_data/quantum_mock.pkl"))
965
+ # Mount applications and endpoints
966
+ mount_app(server, "/agent", agent_app)
967
+ mount_app(server, "/tools", tools_app)
789
968
 
790
- # Load and replay the mock agent
791
- loaded_mock = AgentMock.load(Path("test_data/quantum_mock.pkl"))
792
- result, nodes = await run_agent(loaded_mock, "any prompt") # Returns recorded nodes
969
+ # Run server
970
+ server.run(host="0.0.0.0", port=8000)
793
971
  ```
794
972
 
795
- ## Chainlit & HTTP Server
796
-
797
- ### Chainlit Integration
798
-
799
- Ready-to-use Chainlit application for interactive agent interfaces.
800
-
801
- ```python
802
- # Run the Chainlit app
803
- # Configuration in aixtools/chainlit.md
804
- # Main app in aixtools/app.py
805
- ```
973
+ **Features:**
974
+ - Application mounting system for modular service composition
975
+ - Integration with `Chainlit` for agent interfaces
976
+ - RESTful API support
977
+ - Middleware support for authentication and logging
806
978
 
807
- ## Programming Utils
979
+ ## Programming Utilities
808
980
 
809
981
  AIXtools provides essential programming utilities for configuration management, data persistence, file operations, and context handling.
810
982
 
@@ -828,7 +1000,7 @@ print(cache["user_preferences"]) # Persists across program restarts
828
1000
 
829
1001
  ### Enum with Description
830
1002
 
831
- Enhanced enum classes with built-in descriptions for better documentation and user interfaces.
1003
+ Enhanced `Enum` classes with built-in descriptions for better documentation and user interfaces.
832
1004
 
833
1005
  ```python
834
1006
  from aixtools.utils.enum_with_description import EnumWithDescription
@@ -896,7 +1068,7 @@ app_config = AppConfig()
896
1068
 
897
1069
  ### File Utilities
898
1070
 
899
- Enhanced file operations with Path support and utility functions.
1071
+ Enhanced file operations with `Path` support and utility functions.
900
1072
 
901
1073
  ```python
902
1074
  from aixtools.utils.files import read_file, write_file, ensure_directory
@@ -918,7 +1090,7 @@ if config_path.exists():
918
1090
 
919
1091
  ### Chainlit Utilities
920
1092
 
921
- Specialized utilities for Chainlit integration and agent display.
1093
+ Specialized utilities for `Chainlit` integration and agent display.
922
1094
 
923
1095
  ```python
924
1096
  from aixtools.utils.chainlit.cl_agent_show import show_agent_response
@@ -937,6 +1109,83 @@ formatted_msg = format_message(
937
1109
  )
938
1110
  ```
939
1111
 
1112
+ ### Truncation Utilities
1113
+
1114
+ Smart truncation utilities for handling large data structures and preventing context overflow in LLM applications.
1115
+
1116
+ ```python
1117
+ from aixtools.utils import (
1118
+ truncate_recursive_obj,
1119
+ truncate_df_to_csv,
1120
+ truncate_text_head_tail,
1121
+ truncate_text_middle,
1122
+ format_truncation_message,
1123
+ TruncationMetadata
1124
+ )
1125
+
1126
+ # Truncate nested JSON/dict structures while preserving structure
1127
+ data = {"items": [f"item_{i}" for i in range(1000)], "description": "A" * 10000}
1128
+ truncated = truncate_recursive_obj(data, max_string_len=100, max_list_len=10)
1129
+
1130
+ # Get truncation metadata
1131
+ result, metadata = truncate_recursive_obj(
1132
+ data,
1133
+ target_size=1000,
1134
+ ensure_size=True,
1135
+ return_metadata=True
1136
+ )
1137
+ print(f"Truncated: {metadata.was_truncated}")
1138
+ print(f"Size: {metadata.original_size} → {metadata.truncated_size}")
1139
+
1140
+ # Truncate DataFrames to CSV with head+tail preview
1141
+ import pandas as pd
1142
+ df = pd.DataFrame({"col1": range(10000), "col2": ["x" * 200] * 10000})
1143
+ csv_output = truncate_df_to_csv(
1144
+ df,
1145
+ max_rows=20, # Show first 10 and last 10 rows
1146
+ max_columns=10, # Show first 5 and last 5 columns
1147
+ max_cell_chars=80, # Truncate cell contents
1148
+ max_row_chars=2000 # Truncate CSV lines
1149
+ )
1150
+
1151
+ # Truncate text preserving head and tail
1152
+ text = "A" * 10000
1153
+ truncated, chars_removed = truncate_text_head_tail(text, head_chars=100, tail_chars=100)
1154
+
1155
+ # Truncate text in the middle
1156
+ truncated, chars_removed = truncate_text_middle(text, max_chars=500)
1157
+
1158
+ # Format truncation messages
1159
+ message = format_truncation_message(
1160
+ original_size=10000,
1161
+ truncated_size=500,
1162
+ unit="chars",
1163
+ recommendation="Consider processing in smaller chunks"
1164
+ )
1165
+ ```
1166
+
1167
+ **Key Features:**
1168
+ - **Structure-preserving truncation** - `truncate_recursive_obj()` maintains dict/list structure while truncating
1169
+ - **DataFrame to CSV truncation** - `truncate_df_to_csv()` shows head+tail rows and left+right columns
1170
+ - **Text truncation strategies** - Head+tail or middle truncation for different use cases
1171
+ - **Type-safe metadata** - `TruncationMetadata` Pydantic model with full type hints
1172
+ - **Size enforcement** - `ensure_size=True` guarantees output fits within target size
1173
+ - **Informative messages** - Automatic generation of user-friendly truncation messages
1174
+
1175
+ **Truncation Metadata:**
1176
+
1177
+ All truncation functions support `return_metadata=True` to get detailed information:
1178
+
1179
+ ```python
1180
+ result, meta = truncate_recursive_obj(data, target_size=1000, return_metadata=True)
1181
+
1182
+ # TruncationMetadata attributes
1183
+ meta.original_size # Original size in characters
1184
+ meta.truncated_size # Final size after truncation
1185
+ meta.was_truncated # Whether truncation occurred
1186
+ meta.strategy # Strategy used: "none", "smart", "middle", "str"
1187
+ ```
1188
+
940
1189
  ### General Utilities
941
1190
 
942
1191
  Common utility functions for everyday programming tasks.