aixtools 0.6.5__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 (111) hide show
  1. aixtools-0.6.5/PKG-INFO +956 -0
  2. aixtools-0.6.5/README.md +918 -0
  3. aixtools-0.6.5/aixtools/.chainlit/config.toml +113 -0
  4. aixtools-0.6.5/aixtools/.chainlit/translations/bn.json +214 -0
  5. aixtools-0.6.5/aixtools/.chainlit/translations/en-US.json +214 -0
  6. aixtools-0.6.5/aixtools/.chainlit/translations/gu.json +214 -0
  7. aixtools-0.6.5/aixtools/.chainlit/translations/he-IL.json +214 -0
  8. aixtools-0.6.5/aixtools/.chainlit/translations/hi.json +214 -0
  9. aixtools-0.6.5/aixtools/.chainlit/translations/ja.json +214 -0
  10. aixtools-0.6.5/aixtools/.chainlit/translations/kn.json +214 -0
  11. aixtools-0.6.5/aixtools/.chainlit/translations/ml.json +214 -0
  12. aixtools-0.6.5/aixtools/.chainlit/translations/mr.json +214 -0
  13. aixtools-0.6.5/aixtools/.chainlit/translations/nl.json +214 -0
  14. aixtools-0.6.5/aixtools/.chainlit/translations/ta.json +214 -0
  15. aixtools-0.6.5/aixtools/.chainlit/translations/te.json +214 -0
  16. aixtools-0.6.5/aixtools/.chainlit/translations/zh-CN.json +214 -0
  17. aixtools-0.6.5/aixtools/__init__.py +11 -0
  18. aixtools-0.6.5/aixtools/_version.py +34 -0
  19. aixtools-0.6.5/aixtools/a2a/app.py +240 -0
  20. aixtools-0.6.5/aixtools/a2a/auth_middleware.py +46 -0
  21. aixtools-0.6.5/aixtools/a2a/google_sdk/__init__.py +0 -0
  22. aixtools-0.6.5/aixtools/a2a/google_sdk/pydantic_ai_adapter/agent_executor.py +269 -0
  23. aixtools-0.6.5/aixtools/a2a/google_sdk/pydantic_ai_adapter/storage.py +26 -0
  24. aixtools-0.6.5/aixtools/a2a/google_sdk/remote_agent_connection.py +104 -0
  25. aixtools-0.6.5/aixtools/a2a/google_sdk/store/__init__.py +0 -0
  26. aixtools-0.6.5/aixtools/a2a/google_sdk/store/alembic.ini +148 -0
  27. aixtools-0.6.5/aixtools/a2a/google_sdk/store/config.py +3 -0
  28. aixtools-0.6.5/aixtools/a2a/google_sdk/store/ensure_database.py +176 -0
  29. aixtools-0.6.5/aixtools/a2a/google_sdk/store/migrations/env.py +97 -0
  30. aixtools-0.6.5/aixtools/a2a/google_sdk/store/migrations/script.py.mako +28 -0
  31. aixtools-0.6.5/aixtools/a2a/google_sdk/store/migrations/versions/68c6975ed20b_added_a2a_sdk_task_table.py +44 -0
  32. aixtools-0.6.5/aixtools/a2a/google_sdk/utils.py +129 -0
  33. aixtools-0.6.5/aixtools/a2a/utils.py +116 -0
  34. aixtools-0.6.5/aixtools/agents/__init__.py +12 -0
  35. aixtools-0.6.5/aixtools/agents/agent.py +264 -0
  36. aixtools-0.6.5/aixtools/agents/agent_batch.py +71 -0
  37. aixtools-0.6.5/aixtools/agents/nodes_to_md.py +201 -0
  38. aixtools-0.6.5/aixtools/agents/nodes_to_message.py +30 -0
  39. aixtools-0.6.5/aixtools/agents/nodes_to_str.py +109 -0
  40. aixtools-0.6.5/aixtools/agents/print_nodes.py +54 -0
  41. aixtools-0.6.5/aixtools/agents/prompt.py +270 -0
  42. aixtools-0.6.5/aixtools/app.py +143 -0
  43. aixtools-0.6.5/aixtools/auth/__init__.py +0 -0
  44. aixtools-0.6.5/aixtools/auth/auth.py +292 -0
  45. aixtools-0.6.5/aixtools/chainlit.md +14 -0
  46. aixtools-0.6.5/aixtools/compliance/__init__.py +9 -0
  47. aixtools-0.6.5/aixtools/compliance/private_data.py +139 -0
  48. aixtools-0.6.5/aixtools/compliance/utils.py +44 -0
  49. aixtools-0.6.5/aixtools/context.py +21 -0
  50. aixtools-0.6.5/aixtools/db/__init__.py +17 -0
  51. aixtools-0.6.5/aixtools/db/database.py +110 -0
  52. aixtools-0.6.5/aixtools/db/vector_db.py +115 -0
  53. aixtools-0.6.5/aixtools/evals/__init__.py +0 -0
  54. aixtools-0.6.5/aixtools/evals/__main__.py +74 -0
  55. aixtools-0.6.5/aixtools/evals/dataset.py +87 -0
  56. aixtools-0.6.5/aixtools/evals/discovery.py +186 -0
  57. aixtools-0.6.5/aixtools/evals/run_evals.py +98 -0
  58. aixtools-0.6.5/aixtools/google/client.py +25 -0
  59. aixtools-0.6.5/aixtools/log_view/__init__.py +17 -0
  60. aixtools-0.6.5/aixtools/log_view/app.py +195 -0
  61. aixtools-0.6.5/aixtools/log_view/display.py +285 -0
  62. aixtools-0.6.5/aixtools/log_view/export.py +51 -0
  63. aixtools-0.6.5/aixtools/log_view/filters.py +41 -0
  64. aixtools-0.6.5/aixtools/log_view/log_utils.py +26 -0
  65. aixtools-0.6.5/aixtools/log_view/node_summary.py +229 -0
  66. aixtools-0.6.5/aixtools/logfilters/__init__.py +7 -0
  67. aixtools-0.6.5/aixtools/logfilters/context_filter.py +72 -0
  68. aixtools-0.6.5/aixtools/logging/__init__.py +30 -0
  69. aixtools-0.6.5/aixtools/logging/log_objects.py +240 -0
  70. aixtools-0.6.5/aixtools/logging/logging_config.py +161 -0
  71. aixtools-0.6.5/aixtools/logging/mcp_log_models.py +102 -0
  72. aixtools-0.6.5/aixtools/logging/mcp_logger.py +172 -0
  73. aixtools-0.6.5/aixtools/logging/model_patch_logging.py +87 -0
  74. aixtools-0.6.5/aixtools/logging/open_telemetry.py +36 -0
  75. aixtools-0.6.5/aixtools/mcp/__init__.py +15 -0
  76. aixtools-0.6.5/aixtools/mcp/client.py +306 -0
  77. aixtools-0.6.5/aixtools/mcp/example_client.py +30 -0
  78. aixtools-0.6.5/aixtools/mcp/example_server.py +22 -0
  79. aixtools-0.6.5/aixtools/mcp/exceptions.py +5 -0
  80. aixtools-0.6.5/aixtools/mcp/fast_mcp_log.py +31 -0
  81. aixtools-0.6.5/aixtools/mcp/faulty_mcp.py +319 -0
  82. aixtools-0.6.5/aixtools/mcp/middleware.py +54 -0
  83. aixtools-0.6.5/aixtools/mcp/server.py +76 -0
  84. aixtools-0.6.5/aixtools/model_patch/model_patch.py +63 -0
  85. aixtools-0.6.5/aixtools/server/__init__.py +23 -0
  86. aixtools-0.6.5/aixtools/server/app_mounter.py +90 -0
  87. aixtools-0.6.5/aixtools/server/path.py +130 -0
  88. aixtools-0.6.5/aixtools/server/utils.py +120 -0
  89. aixtools-0.6.5/aixtools/testing/__init__.py +9 -0
  90. aixtools-0.6.5/aixtools/testing/agent_mock.py +143 -0
  91. aixtools-0.6.5/aixtools/testing/aix_test_model.py +186 -0
  92. aixtools-0.6.5/aixtools/testing/mock_tool.py +66 -0
  93. aixtools-0.6.5/aixtools/testing/model_patch_cache.py +279 -0
  94. aixtools-0.6.5/aixtools/tools/doctor/__init__.py +3 -0
  95. aixtools-0.6.5/aixtools/tools/doctor/mcp_tool_doctor.py +79 -0
  96. aixtools-0.6.5/aixtools/tools/doctor/tool_doctor.py +65 -0
  97. aixtools-0.6.5/aixtools/tools/doctor/tool_recommendation.py +49 -0
  98. aixtools-0.6.5/aixtools/utils/__init__.py +35 -0
  99. aixtools-0.6.5/aixtools/utils/chainlit/cl_agent_show.py +82 -0
  100. aixtools-0.6.5/aixtools/utils/chainlit/cl_utils.py +168 -0
  101. aixtools-0.6.5/aixtools/utils/config.py +175 -0
  102. aixtools-0.6.5/aixtools/utils/config_util.py +69 -0
  103. aixtools-0.6.5/aixtools/utils/enum_with_description.py +37 -0
  104. aixtools-0.6.5/aixtools/utils/files.py +17 -0
  105. aixtools-0.6.5/aixtools/utils/persisted_dict.py +99 -0
  106. aixtools-0.6.5/aixtools/utils/utils.py +199 -0
  107. aixtools-0.6.5/aixtools/vault/__init__.py +7 -0
  108. aixtools-0.6.5/aixtools/vault/vault.py +137 -0
  109. aixtools-0.6.5/aixtools.egg-info/SOURCES.txt +108 -0
  110. aixtools-0.6.5/pyproject.toml +81 -0
  111. aixtools-0.6.5/setup.cfg +4 -0
@@ -0,0 +1,956 @@
1
+ Metadata-Version: 2.4
2
+ Name: aixtools
3
+ Version: 0.6.5
4
+ Summary: Tools for AI exploration and debugging
5
+ Requires-Python: >=3.11.2
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: a2a-sdk>=0.3.1
8
+ Requires-Dist: alembic>=1.17.1
9
+ Requires-Dist: cachebox>=5.0.1
10
+ Requires-Dist: chainlit>=2.5.5
11
+ Requires-Dist: colorlog>=6.9.0
12
+ Requires-Dist: fasta2a>=0.5.0
13
+ Requires-Dist: fastmcp>=2.13.0
14
+ Requires-Dist: hvac>=2.3.0
15
+ Requires-Dist: ipykernel>=6.29.5
16
+ Requires-Dist: langchain-chroma>=0.2.3
17
+ Requires-Dist: langchain-ollama>=0.3.2
18
+ Requires-Dist: langchain-openai>=0.3.14
19
+ Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.3
20
+ Requires-Dist: mcp>=1.20.0
21
+ Requires-Dist: mypy>=1.18.2
22
+ Requires-Dist: pandas>=2.2.3
23
+ Requires-Dist: psycopg2-binary>=2.9.11
24
+ Requires-Dist: pydantic-evals>=0.4.10
25
+ Requires-Dist: pydantic-ai>=1.11.1
26
+ Requires-Dist: pyjwt>=2.10.1
27
+ Requires-Dist: pylint>=3.3.7
28
+ Requires-Dist: rich>=14.0.0
29
+ Requires-Dist: ruff>=0.11.6
30
+ Requires-Dist: sqlalchemy>=2.0.44
31
+ Requires-Dist: streamlit>=1.44.1
32
+ Requires-Dist: tiktoken>=0.9.0
33
+ Requires-Dist: watchdog>=6.0.0
34
+ Provides-Extra: test
35
+ Requires-Dist: pyyaml; extra == "test"
36
+ Provides-Extra: feature
37
+ Requires-Dist: logfire; extra == "feature"
38
+
39
+ # AIXtools
40
+
41
+ AIXtools is a comprehensive Python library for AI agent development, debugging, and deployment. It provides a complete toolkit for building, testing, and monitoring AI agents with support for multiple model providers, advanced logging, and agent-to-agent communication.
42
+
43
+ ## Capabilities
44
+
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`
89
+
90
+ ## Installation
91
+
92
+ ```bash
93
+ uv add aixtools
94
+ ```
95
+
96
+ **Updating**
97
+
98
+ ```bash
99
+ uv add --upgrade aixtools
100
+ ```
101
+
102
+ ## Environment Configuration
103
+
104
+ AIXtools requires environment variables for model providers.
105
+
106
+ **IMPORTANT:** Create a `.env` file based on [`.env_template`](./.env_template):
107
+
108
+ Here is an example configuration:
109
+ ```bash
110
+ # Model family (azure, openai, or ollama)
111
+ MODEL_FAMILY=azure
112
+ MODEL_TIMEOUT=120
113
+
114
+ # Azure OpenAI
115
+ AZURE_OPENAI_ENDPOINT=https://your_endpoint.openai.azure.com
116
+ AZURE_OPENAI_API_VERSION=2024-06-01
117
+ AZURE_OPENAI_API_KEY=your_secret_key
118
+ AZURE_MODEL_NAME=gpt-4o
119
+
120
+ # OpenAI
121
+ OPENAI_MODEL_NAME=gpt-4.5-preview
122
+ OPENAI_API_KEY=openai_api_key
123
+
124
+ # Ollama
125
+ OLLAMA_MODEL_NAME=llama3.2:3b-instruct-fp16
126
+ OLLAMA_LOCAL_URL=http://localhost:11434/v1
127
+ ```
128
+
129
+ ## Agents
130
+
131
+ ### Basic Agent Usage
132
+
133
+ ```python
134
+ from aixtools.agents.agent import get_agent, run_agent
135
+
136
+ async def main():
137
+ agent = get_agent(system_prompt="You are a helpful assistant.")
138
+ result, nodes = await run_agent(agent, "Explain quantum computing")
139
+ print(result)
140
+ ```
141
+
142
+ ### Agent Development & Management
143
+
144
+ The agent system provides a unified interface for creating and managing AI agents across different model providers.
145
+
146
+ ```python
147
+ from aixtools.agents.agent import get_agent, run_agent
148
+
149
+ # Create an agent with default model
150
+ agent = get_agent(system_prompt="You are a helpful assistant.")
151
+
152
+ # Run the agent
153
+ result, nodes = await run_agent(agent, "Tell me about AI")
154
+ ```
155
+
156
+ ### Node Debugging and Visualization
157
+
158
+ The [`print_nodes`](aixtools/agents/print_nodes.py) module provides a clean, indented output for easy reading of the node from agent execution.
159
+
160
+ ```python
161
+ from aixtools.agents.print_nodes import print_nodes, print_node
162
+ from aixtools.agents.agent import get_agent, run_agent
163
+
164
+ agent = get_agent(system_prompt="You are a helpful assistant.")
165
+ result, nodes = await run_agent(agent, "Explain quantum computing")
166
+ # Print all execution nodes for debugging
167
+ print_nodes(nodes)
168
+ ```
169
+
170
+ **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
176
+
177
+ **Node Types Supported:**
178
+ - `UserPromptNode` - Displays user prompts with indentation
179
+ - `CallToolsNode` - Shows tool calls with names and arguments
180
+ - `ModelRequestNode` - Summarizes model requests with character count
181
+ - `End` - Marks the end of execution (output suppressed by default)
182
+
183
+ ### Agent Batch Processing
184
+
185
+ Process multiple agent queries simultaneously with built-in concurrency control and result aggregation.
186
+
187
+ ```python
188
+ from aixtools.agents.agent_batch import agent_batch, AgentQueryParams
189
+
190
+ # Create query parameters
191
+ query_parameters = [
192
+ AgentQueryParams(prompt="What is the meaning of life"),
193
+ AgentQueryParams(prompt="Who is the prime minister of Canada")
194
+ ]
195
+
196
+ # Run queries in batches
197
+ async for result in agent_batch(query_parameters):
198
+ print(result)
199
+ ```
200
+
201
+ ## A2A (Agent-to-Agent Communication)
202
+
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.
204
+
205
+ ### Core Features
206
+
207
+ **Agent Application Conversion**
208
+ - Convert PydanticAI agents into FastA2A applications (deprecated)
209
+ - Support for session metadata extraction and context management
210
+ - Custom worker classes with enhanced data part support
211
+ - Automatic handling of user and session identification
212
+
213
+ **Remote Agent Connections**
214
+ - Establish connections between agents across different environments
215
+ - Asynchronous message sending with task polling capabilities
216
+ - Terminal state detection and error handling
217
+ - Support for various message types including text, files, and data
218
+
219
+ **Google SDK Integration**
220
+ - Native integration with Google's A2A SDK
221
+ - Card-based agent representation and discovery
222
+ - PydanticAI adapter for seamless Google SDK compatibility
223
+ - Storage and execution management for agent interactions
224
+
225
+ ### Agent-to-Agent Communication (A2A)
226
+
227
+ Enable sophisticated agent interactions with Google SDK integration and PydanticAI adapters.
228
+
229
+ ```python
230
+ from aixtools.a2a.google_sdk.remote_agent_connection import RemoteAgentConnection
231
+ from aixtools.a2a.app import agent_to_a2a
232
+
233
+ # Convert a PydanticAI agent to FastA2A application
234
+ a2a_app = agent_to_a2a(
235
+ agent=my_agent,
236
+ name="MyAgent",
237
+ description="A helpful AI assistant",
238
+ skills=[{"name": "chat", "description": "General conversation"}]
239
+ )
240
+
241
+ # Connect agents across different environments
242
+ connection = RemoteAgentConnection(card=agent_card, client=a2a_client)
243
+ response = await connection.send_message_with_polling(message)
244
+ ```
245
+
246
+ ### Postgres DB Store for A2A agent
247
+
248
+ See implementation: `aixtools/a2a/google_sdk/store`
249
+
250
+ #### Alembic
251
+
252
+ In order to take full control of the database schema management Alembic is used for handling database migrations.
253
+ Thus make sure, that google-sdk Store objects are being created with parameter create_table=False
254
+ ```python
255
+ from a2a.server.tasks import DatabaseTaskStore
256
+
257
+ ...
258
+
259
+ task_store=DatabaseTaskStore(engine=db_engine, create_table=False)
260
+ ```
261
+
262
+ #### Setup of database and applying migrations (manual if needed):
263
+
264
+ configure POSTGRES_URL env variable
265
+ ```.dotenv
266
+ POSTGRES_URL=postgresql+asyncpg://user:password@localhost:5432/a2a_magic_db
267
+ ```
268
+
269
+
270
+ ```shell
271
+ # from scope of your a2a service
272
+
273
+ #activate your virtual environment
274
+ kzwk877@degfqx35d621DD a2a_magic_service % source .venv/bin/activate
275
+ # set the PATH_TO_ALEMBIC_CONFIG environment variable to point to the alembic configuration directory
276
+ (a2a_magic_service) kzwk877@degfqx35d621DD a2a_magic_service % export PATH_TO_ALEMBIC_CONFIG="$(pwd)/.venv/lib/python3.12/site-packages/aixtools/a2a/google_sdk/store"
277
+ # Make sure that database is existed
278
+ (a2a_magic_service) kzwk877@degfqx35d621DD a2a_magic_service % uv run "${PATH_TO_ALEMBIC_CONFIG}/ensure_database.py"
279
+ 2025-11-11 10:08:51.501 WARNING [root] Looking for '.env' file in default directory
280
+ 2025-11-11 10:08:52.750 INFO [root] Using .env file at '/PATH_TO_A2A_SERVICE/a2a_magic_service/.env'
281
+ 2025-11-11 10:08:52.751 INFO [root] Using MAIN_PROJECT_DIR='/PATH_TO_A2A_SERVICE/a2a_magic_service'
282
+ 2025-11-11 10:08:52.752 WARNING [root] Using DATA_DIR='/app/data'
283
+ 2025-11-11 10:08:52.757 INFO [__main__] Starting database creation script...
284
+ ...
285
+ 2025-11-11 10:08:52.821 INFO [__main__] Creating database 'a2a_magic_db'...
286
+ 2025-11-11 10:08:52.904 INFO [__main__] Database 'a2a_magic_db' created successfully
287
+ ...
288
+ 2025-11-11 10:08:52.921 INFO [__main__] Database creation script completed successfully!
289
+ # Apply alembic migrations
290
+ (a2a_magic_service) kzwk877@degfqx35d621DD a2a_magic_service % alembic --config "${PATH_TO_ALEMBIC_CONFIG}/alembic.ini" upgrade head
291
+ 2025-11-11 10:11:34.185 WARNING [root] Looking for '.env' file in default directory
292
+ 2025-11-11 10:11:35.046 WARNING [root] Looking for '.env' file at '/PATH_TO_A2A_SERVICE/a2a_magic_service'
293
+ 2025-11-11 10:11:35.047 INFO [root] Using .env file at '/PATH_TO_A2A_SERVICE/a2a_magic_service/.env'
294
+ 2025-11-11 10:11:35.048 INFO [root] Using MAIN_PROJECT_DIR='/PATH_TO_A2A_SERVICE/a2a_magic_service'
295
+ 2025-11-11 10:11:35.049 WARNING [root] Using DATA_DIR='/app/data'
296
+ 2025-11-11 10:11:35.054 INFO [env_py] Using database URL for migrations: postgresql://user:password@localhost:5432/a2a_magic_db
297
+ INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
298
+ INFO [alembic.runtime.migration] Will assume transactional DDL.
299
+ INFO [alembic.runtime.migration] Running upgrade -> 68c6975ed20b, Added a2a-sdk Task table
300
+ ```
301
+
302
+ #### Schema modifications
303
+
304
+ if new schema modifications has been introduced with new versions of a2a sdk suggested way
305
+ to create new alembic migrations would be:
306
+
307
+ - launch a2a service with passed parameter to `DatabaseStore` `create_table=True`
308
+ - make sure that all new tables/columns are created in
309
+ the database (possibly an new request to a2a server needs to be made)
310
+ - create new alembic migration script
311
+ ```shell
312
+ (a2a_magic_service) kzwk877@degfqx35d621DD % alembic --config "${PATH_TO_ALEMBIC_CONFIG}/alembic.ini" revision --autogenerate -m "New table introduced"
313
+ ```
314
+ - review the generated migration script
315
+ - apply and test
316
+
317
+ ## Databases
318
+
319
+ ### Database Integration
320
+
321
+ Support for both traditional and vector databases with seamless integration.
322
+
323
+ ```python
324
+ from aixtools.db.database import Database
325
+ from aixtools.db.vector_db import VectorDB
326
+
327
+ # Traditional database
328
+ db = Database("sqlite:///app.db")
329
+
330
+ # Vector database for embeddings
331
+ vector_db = VectorDB()
332
+ vector_db.add_documents(documents)
333
+ ```
334
+
335
+ ## Logging & Debugging
336
+
337
+ AixTools provides functionality for logging and debugging.
338
+
339
+ ### Basic Logging and Debugging
340
+
341
+ ```python
342
+ from aixtools.agents.agent import get_agent, run_agent
343
+
344
+ async def main():
345
+ # Create an agent
346
+ agent = get_agent(system_prompt="You are a helpful assistant.")
347
+
348
+ # Run agent - logging is automatic via ObjectLogger
349
+ result, nodes = await run_agent(
350
+ agent,
351
+ "Explain quantum computing",
352
+ debug=True, # Enable debug logging
353
+ log_model_requests=True # Log model requests/responses
354
+ )
355
+
356
+ print(f"Result: {result}")
357
+ print(f"Logged {len(nodes)} nodes")
358
+ ```
359
+
360
+ ### Log Viewing Application
361
+
362
+ Interactive Streamlit application for analyzing logged objects and debugging agent behavior.
363
+
364
+ **Features:**
365
+ - Log file selection and filtering
366
+ - Node visualization with expand/collapse
367
+ - Export capabilities to JSON
368
+ - Regex pattern matching
369
+ - Real-time log monitoring
370
+
371
+ ```bash
372
+ # Run the log viewer
373
+ log_view
374
+
375
+ # Or specify custom log directory
376
+ log_view /path/to/logs
377
+ ```
378
+
379
+ ### Object Logging & Debugging
380
+
381
+ Advanced logging system with object serialization and visual debugging tools.
382
+
383
+ ```python
384
+ from aixtools.logging.log_objects import ObjectLogger
385
+
386
+ # Log any pickleable object
387
+ with ObjectLogger() as logger:
388
+ logger.log({"message": "Hello, world!"})
389
+ logger.log(agent_response)
390
+ ```
391
+
392
+ ### MCP logging
393
+
394
+ AIXtools provides MCP support for both client and server implementations with easier logging for debugging pourposes.
395
+
396
+ **Example:**
397
+
398
+ Let's assume we have an MCP server that runs an agent tool.
399
+
400
+ Note that the `ctx: Context` parameter is passed to `run_agent`, this will enable logging to the MCP client.
401
+
402
+ ```python
403
+ @mcp.tool
404
+ async def my_tool_with_agent(query: str, ctx: Context) -> str:
405
+ """ A tool that uses an gents to process the query """
406
+ agent = get_agent()
407
+ async with get_qb_agent() as agent:
408
+ ret, nodes = await run_agent(agent=agent, prompt=query, ctx=ctx) # Enable MCP logging
409
+ return str(ret)
410
+ ```
411
+
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
413
+
414
+ ```python
415
+ mcp = get_mcp_client("http://localhost:8000") # Get an MCP client with a default log handler that prints to STDOUT
416
+ agent = get_agent(toolsets=[mcp])
417
+ async with agent:
418
+ # The messages from the MCP server will be printed to the STDOUT
419
+ ret, nodes = await run_agent(agent, prompt="...")
420
+ ```
421
+
422
+ #### MCP Server Logging
423
+
424
+ Create MCP servers with built-in logging capabilities.
425
+
426
+ ```python
427
+ from aixtools.mcp.fast_mcp_log import FastMcpLog
428
+
429
+ # Use FastMCP server with logging
430
+ mcp = FastMcpLog("Demo")
431
+ ```
432
+
433
+ ### Model Patching System
434
+
435
+ Dynamic model behavior modification for testing and debugging.
436
+
437
+ ```python
438
+ from aixtools.model_patch.model_patch import ModelPatch
439
+
440
+ # Apply patches to models for testing
441
+ with ModelPatch() as patch:
442
+ patch.apply_response_override("test response")
443
+ result = await agent.run("test prompt")
444
+ ```
445
+
446
+ ### FaultyMCP
447
+
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.
449
+
450
+ **Features:**
451
+ - Configurable error probabilities for different request types
452
+ - HTTP 404 error injection for POST/DELETE requests
453
+ - Server crash simulation on GET requests
454
+ - Random exception throwing in tool operations
455
+ - MCP-specific error simulation (ValidationError, ResourceError, etc.)
456
+ - Safe mode for controlled testing
457
+
458
+ ```python
459
+ from aixtools.mcp.faulty_mcp import run_server_on_port, config
460
+
461
+ # Configure error probabilities
462
+ config.prob_on_post_404 = 0.3 # 30% chance of 404 on POST
463
+ config.prob_on_get_crash = 0.1 # 10% chance of crash on GET
464
+ config.prob_in_list_tools_throw = 0.2 # 20% chance of exception in tools/list
465
+
466
+ # Run the faulty server
467
+ run_server_on_port()
468
+ ```
469
+
470
+ **Command Line Usage:**
471
+ ```bash
472
+ # Run with default error probabilities
473
+ python -m aixtools.mcp.faulty_mcp
474
+
475
+ # Run in safe mode (no errors by default)
476
+ python -m aixtools.mcp.faulty_mcp --safe-mode
477
+
478
+ # Custom configuration
479
+ python -m aixtools.mcp.faulty_mcp \
480
+ --port 8888 \
481
+ --prob-on-post-404 0.2 \
482
+ --prob-on-get-crash 0.1 \
483
+ --prob-in-list-tools-throw 0.3
484
+ ```
485
+
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)
489
+ - `always_error()` - Always throws an exception
490
+ - `random_throw_exception(a, b, prob)` - Randomly throws exceptions
491
+ - `freeze_server(seconds)` - Simulates server freeze
492
+ - `throw_404_exception()` - Throws HTTP 404 error
493
+
494
+ ### Evals
495
+
496
+ Run comprehensive Agent/LLM evaluations using the built-in evaluation discovery based on Pydantic-AI framework with AIXtools enhancements.
497
+
498
+ ```bash
499
+ # Run all evaluations
500
+ python -m aixtools.evals
501
+
502
+ # Run evaluations with filtering
503
+ python -m aixtools.evals --filter "specific_test"
504
+
505
+ # Run with verbose output and detailed reporting
506
+ python -m aixtools.evals --verbose --include-input --include-output --include-reasons
507
+
508
+ # Specify custom evaluations directory
509
+ python -m aixtools.evals --evals-dir /path/to/evals
510
+
511
+ # Set minimum assertions threshold
512
+ python -m aixtools.evals --min-assertions 0.8
513
+ ```
514
+
515
+ **Command Line Options:**
516
+ - `--evals-dir` - Directory containing eval_*.py files (default: evals)
517
+ - `--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)
520
+ - `--include-evaluator-failures` - Include evaluator failures in report
521
+ - `--include-reasons` - Include reasons in report output
522
+ - `--min-assertions` - Minimum assertions average required for success (default: 1.0)
523
+ - `--verbose` - Print detailed information about discovery and processing
524
+
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.
526
+
527
+ **Discovery Mechanism**
528
+
529
+ The evaluation framework uses an automatic discovery system:
530
+
531
+ 1. **File Discovery**: Scans the specified directory for files matching the pattern `eval_*.py`
532
+ 2. **Dataset Discovery**: Within each file, looks for variables named `dataset_*` that are instances of `pydantic_evals.Dataset`
533
+ 3. **Target Function Discovery**: Within the same file looks for function or async function named `target_*`. There must be 1 target function per file.
534
+ 4. **Function Discovery**: Looks for functions with specific prefixes:
535
+ - Functions prefixed with `scorer_*`, `evaluator_*` for custom scorer and evaluator functions that will be used for each dataset in that file
536
+ 5. **Filtering**: Supports filtering by module name, file name, dataset name, or fully qualified name
537
+
538
+ **Example Evaluation File Structure:**
539
+ ```python
540
+ # eval_math_operations.py
541
+ from pydantic_evals import Dataset, Case
542
+
543
+ # This dataset will be discovered automatically
544
+ dataset_addition = Dataset(
545
+ name="Addition Tests",
546
+ cases=[
547
+ Case(input="What is 2 + 2?", expected="4"),
548
+ Case(input="What is 10 + 5?", expected="15"),
549
+ ],
550
+ evaluators=[...]
551
+ )
552
+
553
+ # This function will be used as the evaluation target
554
+ async def target_math_agent(input_text: str) -> str:
555
+ # Your agent run logic here
556
+ agent = get_agent(system_prompt="You are a math assistant.")
557
+ result, _ = await run_agent(agent, input_text)
558
+ return result
559
+
560
+ # This function will be used as evaluator for all datasets (optional)
561
+ def evaluator_check_output(ctx: EvaluatorContext) -> bool:
562
+ # Your result evaluation logic here
563
+ return ctx.output == ctx.expected_output
564
+ ```
565
+
566
+ The discovery system will:
567
+ - Find `eval_math_operations.py` in the evals directory
568
+ - Discover `dataset_addition` as an evaluation dataset
569
+ - Use `evaluate_math_agent` as the target function for evaluation
570
+ - Run each case through the target function and evaluate results
571
+
572
+ #### Name-Based Discovery
573
+
574
+ The evaluation system uses name-based discovery for all components:
575
+
576
+ **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`
581
+
582
+ **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`
587
+
588
+ **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`
593
+
594
+ This name-based approach works seamlessly with both synchronous and asynchronous functions.
595
+
596
+ #### Scoring System
597
+
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
+ ```
715
+
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
+ ```
732
+
733
+ ### FaultyMCP Testing Server
734
+
735
+ Specialized MCP server for testing error handling and resilience in MCP implementations.
736
+
737
+ ```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
770
+ ```
771
+
772
+ ### Agent Mock
773
+
774
+ Replay previously recorded agent runs without executing the actual agent. Useful for testing, debugging, and creating reproducible test cases.
775
+
776
+ ```python
777
+ from aixtools.testing.agent_mock import AgentMock
778
+ from aixtools.agents.agent import get_agent, run_agent
779
+
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")
783
+
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"))
789
+
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
793
+ ```
794
+
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
+ ```
806
+
807
+ ## Programming Utils
808
+
809
+ AIXtools provides essential programming utilities for configuration management, data persistence, file operations, and context handling.
810
+
811
+ ### Persisted Dictionary
812
+
813
+ Persistent key-value storage with automatic serialization and file-based persistence.
814
+
815
+ ```python
816
+ from aixtools.utils.persisted_dict import PersistedDict
817
+
818
+ # Create a persistent dictionary
819
+ cache = PersistedDict("cache.json")
820
+
821
+ # Store and retrieve data
822
+ cache["user_preferences"] = {"theme": "dark", "language": "en"}
823
+ cache["session_data"] = {"last_login": "2024-01-01"}
824
+
825
+ # Data is automatically saved to file
826
+ print(cache["user_preferences"]) # Persists across program restarts
827
+ ```
828
+
829
+ ### Enum with Description
830
+
831
+ Enhanced enum classes with built-in descriptions for better documentation and user interfaces.
832
+
833
+ ```python
834
+ from aixtools.utils.enum_with_description import EnumWithDescription
835
+
836
+ class ModelType(EnumWithDescription):
837
+ GPT4 = ("gpt-4", "OpenAI GPT-4 model")
838
+ CLAUDE = ("claude-3", "Anthropic Claude-3 model")
839
+ LLAMA = ("llama-2", "Meta LLaMA-2 model")
840
+
841
+ # Access enum values and descriptions
842
+ print(ModelType.GPT4.value) # "gpt-4"
843
+ print(ModelType.GPT4.description) # "OpenAI GPT-4 model"
844
+
845
+ # Get all descriptions
846
+ for model in ModelType:
847
+ print(f"{model.value}: {model.description}")
848
+ ```
849
+
850
+ ### Context Management
851
+
852
+ Centralized context management for sharing state across components.
853
+
854
+ ```python
855
+ from aixtools.context import Context
856
+
857
+ # Create and use context
858
+ context = Context()
859
+ context.set("user_id", "12345")
860
+ context.set("session_data", {"preferences": {"theme": "dark"}})
861
+
862
+ # Retrieve context data
863
+ user_id = context.get("user_id")
864
+ session_data = context.get("session_data")
865
+
866
+ # Context can be passed between components
867
+ def process_request(ctx: Context):
868
+ user_id = ctx.get("user_id")
869
+ # Process with user context
870
+ ```
871
+
872
+ ### Configuration Management
873
+
874
+ Robust configuration handling with environment variable support and validation.
875
+
876
+ ```python
877
+ from aixtools.utils.config import Config
878
+ from aixtools.utils.config_util import load_config
879
+
880
+ # Load configuration from environment and files
881
+ config = load_config()
882
+
883
+ # Access configuration values
884
+ model_name = config.get("MODEL_NAME", "gpt-4")
885
+ api_key = config.get("API_KEY")
886
+ timeout = config.get("TIMEOUT", 30, int)
887
+
888
+ # Configuration with validation
889
+ class AppConfig(Config):
890
+ model_name: str = "gpt-4"
891
+ max_tokens: int = 1000
892
+ temperature: float = 0.7
893
+
894
+ app_config = AppConfig()
895
+ ```
896
+
897
+ ### File Utilities
898
+
899
+ Enhanced file operations with Path support and utility functions.
900
+
901
+ ```python
902
+ from aixtools.utils.files import read_file, write_file, ensure_directory
903
+ from pathlib import Path
904
+
905
+ # Read and write files with automatic encoding handling
906
+ content = read_file("data.txt")
907
+ write_file("output.txt", "Hello, world!")
908
+
909
+ # Ensure directories exist
910
+ data_dir = Path("data/logs")
911
+ ensure_directory(data_dir)
912
+
913
+ # Work with file paths
914
+ config_path = Path("config") / "settings.json"
915
+ if config_path.exists():
916
+ config_data = read_file(config_path)
917
+ ```
918
+
919
+ ### Chainlit Utilities
920
+
921
+ Specialized utilities for Chainlit integration and agent display.
922
+
923
+ ```python
924
+ from aixtools.utils.chainlit.cl_agent_show import show_agent_response
925
+ from aixtools.utils.chainlit.cl_utils import format_message
926
+
927
+ # Display agent responses in Chainlit
928
+ await show_agent_response(
929
+ response="Hello, how can I help you?",
930
+ metadata={"model": "gpt-4", "tokens": 150}
931
+ )
932
+
933
+ # Format messages for Chainlit display
934
+ formatted_msg = format_message(
935
+ content="Processing your request...",
936
+ message_type="info"
937
+ )
938
+ ```
939
+
940
+ ### General Utilities
941
+
942
+ Common utility functions for everyday programming tasks.
943
+
944
+ ```python
945
+ from aixtools.utils.utils import safe_json_loads, timestamp_now, hash_string
946
+
947
+ # Safe JSON parsing
948
+ data = safe_json_loads('{"key": "value"}', default={})
949
+
950
+ # Get current timestamp
951
+ now = timestamp_now()
952
+
953
+ # Generate hash for strings
954
+ file_hash = hash_string("content to hash")
955
+ ```
956
+