aixtools 0.1.0__py3-none-any.whl
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.
Potentially problematic release.
This version of aixtools might be problematic. Click here for more details.
- aixtools/__init__.py +5 -0
- aixtools/a2a/__init__.py +5 -0
- aixtools/a2a/app.py +126 -0
- aixtools/a2a/utils.py +115 -0
- aixtools/agents/__init__.py +12 -0
- aixtools/agents/agent.py +164 -0
- aixtools/agents/agent_batch.py +74 -0
- aixtools/app.py +143 -0
- aixtools/context.py +12 -0
- aixtools/db/__init__.py +17 -0
- aixtools/db/database.py +110 -0
- aixtools/db/vector_db.py +115 -0
- aixtools/log_view/__init__.py +17 -0
- aixtools/log_view/app.py +195 -0
- aixtools/log_view/display.py +285 -0
- aixtools/log_view/export.py +51 -0
- aixtools/log_view/filters.py +41 -0
- aixtools/log_view/log_utils.py +26 -0
- aixtools/log_view/node_summary.py +229 -0
- aixtools/logfilters/__init__.py +7 -0
- aixtools/logfilters/context_filter.py +67 -0
- aixtools/logging/__init__.py +30 -0
- aixtools/logging/log_objects.py +227 -0
- aixtools/logging/logging_config.py +116 -0
- aixtools/logging/mcp_log_models.py +102 -0
- aixtools/logging/mcp_logger.py +172 -0
- aixtools/logging/model_patch_logging.py +87 -0
- aixtools/logging/open_telemetry.py +36 -0
- aixtools/mcp/__init__.py +9 -0
- aixtools/mcp/example_client.py +30 -0
- aixtools/mcp/example_server.py +22 -0
- aixtools/mcp/fast_mcp_log.py +31 -0
- aixtools/mcp/faulty_mcp.py +320 -0
- aixtools/model_patch/model_patch.py +65 -0
- aixtools/server/__init__.py +23 -0
- aixtools/server/app_mounter.py +90 -0
- aixtools/server/path.py +72 -0
- aixtools/server/utils.py +70 -0
- aixtools/testing/__init__.py +9 -0
- aixtools/testing/aix_test_model.py +147 -0
- aixtools/testing/mock_tool.py +66 -0
- aixtools/testing/model_patch_cache.py +279 -0
- aixtools/tools/doctor/__init__.py +3 -0
- aixtools/tools/doctor/tool_doctor.py +61 -0
- aixtools/tools/doctor/tool_recommendation.py +44 -0
- aixtools/utils/__init__.py +35 -0
- aixtools/utils/chainlit/cl_agent_show.py +82 -0
- aixtools/utils/chainlit/cl_utils.py +168 -0
- aixtools/utils/config.py +118 -0
- aixtools/utils/config_util.py +69 -0
- aixtools/utils/enum_with_description.py +37 -0
- aixtools/utils/persisted_dict.py +99 -0
- aixtools/utils/utils.py +160 -0
- aixtools-0.1.0.dist-info/METADATA +355 -0
- aixtools-0.1.0.dist-info/RECORD +58 -0
- aixtools-0.1.0.dist-info/WHEEL +5 -0
- aixtools-0.1.0.dist-info/entry_points.txt +2 -0
- aixtools-0.1.0.dist-info/top_level.txt +1 -0
aixtools/utils/utils.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""
|
|
2
|
+
General utility functions for string manipulation, logging, and data handling.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import uuid
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
DF_SHOW_MAX_ROWS = 20
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def escape_newline(s, max_length: int = 300) -> str:
|
|
16
|
+
"""Escape newlines in a string."""
|
|
17
|
+
s = str(s)
|
|
18
|
+
ss = "\\n".join(s.split("\n"))
|
|
19
|
+
if len(ss) <= max_length:
|
|
20
|
+
return ss
|
|
21
|
+
return "".join(ss[:max_length]) + "..."
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def escape_backticks(s) -> str:
|
|
25
|
+
"""Escape backticks in a string."""
|
|
26
|
+
s = f"{s}"
|
|
27
|
+
return s.replace("`", "\\`")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def find_file(path: Path, glob="*.pdf"):
|
|
31
|
+
"""Recursively find all files matching the glob pattern in a directory"""
|
|
32
|
+
yield from path.rglob(glob)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def prepend_all_lines(msg, prepend="\t", skip_first_line: bool = False) -> str:
|
|
36
|
+
"""Prepend all lines of a message with a prepend."""
|
|
37
|
+
out = ""
|
|
38
|
+
for i, line in enumerate(str(msg).split("\n")):
|
|
39
|
+
if i == 0 and skip_first_line:
|
|
40
|
+
out += f"{line}\n"
|
|
41
|
+
else:
|
|
42
|
+
out += f"{prepend}{line}\n"
|
|
43
|
+
return out
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def remove_quotes(s):
|
|
47
|
+
"""
|
|
48
|
+
Remove all quotes (including triple backticks with language specifications) surrounding a string.
|
|
49
|
+
|
|
50
|
+
This function strips the input string of all surrounding quotes, including single quotes, double quotes,
|
|
51
|
+
backticks, and triple backticks with or without language specifications. It continues to remove quotes
|
|
52
|
+
until none are left.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
s (str): The input string potentially surrounded by quotes.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
str: The string with all surrounding quotes removed. If the input is None, returns None.
|
|
59
|
+
"""
|
|
60
|
+
if s is None:
|
|
61
|
+
return None
|
|
62
|
+
s = s.strip()
|
|
63
|
+
while (
|
|
64
|
+
(s.startswith('"') and s.endswith('"'))
|
|
65
|
+
or (s.startswith("'") and s.endswith("'"))
|
|
66
|
+
or (s.startswith("`") and s.endswith("`"))
|
|
67
|
+
or ("```" in s)
|
|
68
|
+
):
|
|
69
|
+
if "```" in s:
|
|
70
|
+
s = tripple_quote_strip(s)
|
|
71
|
+
else:
|
|
72
|
+
# Single quotes
|
|
73
|
+
s = s[1:-1].strip()
|
|
74
|
+
# Remove spaces
|
|
75
|
+
s = s.strip()
|
|
76
|
+
return s
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def tabit(s: str, prefix="\t|") -> str:
|
|
80
|
+
"""Add a prefix to each line of a string for improved readability."""
|
|
81
|
+
return prefix + str(s).replace("\n", f"\n{prefix}")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def to_str(data) -> str:
|
|
85
|
+
"""Convert any data type to a readable string representation."""
|
|
86
|
+
# Primitive values, just use str()
|
|
87
|
+
if isinstance(data, str):
|
|
88
|
+
return f"'{str}'"
|
|
89
|
+
if isinstance(data, (bool, bytes, float, int)):
|
|
90
|
+
return str(data)
|
|
91
|
+
# Dataframes
|
|
92
|
+
if isinstance(data, pd.DataFrame):
|
|
93
|
+
if data.shape[0] > DF_SHOW_MAX_ROWS:
|
|
94
|
+
return f"Showing only the first {DF_SHOW_MAX_ROWS} rows out of {data.shape[0]}:\n" + data.head(
|
|
95
|
+
DF_SHOW_MAX_ROWS
|
|
96
|
+
).to_markdown(index=False)
|
|
97
|
+
return data.to_markdown(index=False)
|
|
98
|
+
# Use json for list, dict, etc.
|
|
99
|
+
if isinstance(data, (dict, list, tuple)):
|
|
100
|
+
return json.dumps(data, indent=2, default=str)
|
|
101
|
+
return str(data)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def truncate(s: str, max_len=76, ellipsis="...") -> str:
|
|
105
|
+
"""Truncate a string to a maximum length, adding ellipsis if needed."""
|
|
106
|
+
s = str(s)
|
|
107
|
+
if len(s) > max_len:
|
|
108
|
+
return s[: max_len - len(ellipsis)] + ellipsis
|
|
109
|
+
return s
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def tripple_quote_strip(s):
|
|
113
|
+
"""
|
|
114
|
+
Remove triple quotes from a string, including those with language specifications.
|
|
115
|
+
|
|
116
|
+
Eexamples:
|
|
117
|
+
```sql SELECT * from table;```
|
|
118
|
+
|
|
119
|
+
```Here is your code ```python c = a + b ``` This code will perform addition```
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
s (str): The input string potentially containing triple quotes.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
str: The string with triple quotes removed, if present.
|
|
126
|
+
"""
|
|
127
|
+
if "```" not in s:
|
|
128
|
+
return s
|
|
129
|
+
left_pos, right_pos = len(s), s.rfind("```")
|
|
130
|
+
s_lower = s.lower()
|
|
131
|
+
pre_matched = ""
|
|
132
|
+
for lang in ["python3", "python2", "python", "bash", "json", "sql", ""]:
|
|
133
|
+
pre = f"```{lang}"
|
|
134
|
+
idx = s_lower.find(pre)
|
|
135
|
+
if idx != -1 and idx < left_pos:
|
|
136
|
+
left_pos = idx
|
|
137
|
+
pre_matched = pre
|
|
138
|
+
if left_pos < right_pos:
|
|
139
|
+
s = s[left_pos + len(pre_matched) : right_pos].strip()
|
|
140
|
+
return s
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def timestamp_with_uuid() -> str:
|
|
144
|
+
"""Get a timestamp string + a UUID string (first 8 chars)."""
|
|
145
|
+
(yyy, hh, uu) = timestamp_uuid_tuple()
|
|
146
|
+
return f"{yyy}.{hh}.{uu[:8]}"
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def timestamp_uuid_tuple() -> tuple[str, str, str]:
|
|
150
|
+
"""
|
|
151
|
+
Get a tuple of timestamp + a UUID: (YYYY-MM-DD, HH:MM:SS, UUID)
|
|
152
|
+
"""
|
|
153
|
+
now = datetime.now()
|
|
154
|
+
return (now.strftime("%Y-%m-%d"), now.strftime("%H:%M:%S"), str(uuid.uuid4()))
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
async def async_iter(items):
|
|
158
|
+
"""Asynchronously iterate over items."""
|
|
159
|
+
for item in items:
|
|
160
|
+
yield item
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aixtools
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Tools for AI exploration and debugging
|
|
5
|
+
Requires-Python: >=3.11.2
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: chainlit>=2.5.5
|
|
8
|
+
Requires-Dist: colorlog>=6.9.0
|
|
9
|
+
Requires-Dist: fasta2a>=0.5.0
|
|
10
|
+
Requires-Dist: fastmcp>=2.10.2
|
|
11
|
+
Requires-Dist: ipykernel>=6.29.5
|
|
12
|
+
Requires-Dist: langchain-chroma>=0.2.3
|
|
13
|
+
Requires-Dist: langchain-ollama>=0.3.2
|
|
14
|
+
Requires-Dist: langchain-openai>=0.3.14
|
|
15
|
+
Requires-Dist: mcp>=1.11.0
|
|
16
|
+
Requires-Dist: pandas>=2.2.3
|
|
17
|
+
Requires-Dist: pydantic-ai>=0.4.10
|
|
18
|
+
Requires-Dist: pylint>=3.3.7
|
|
19
|
+
Requires-Dist: rich>=14.0.0
|
|
20
|
+
Requires-Dist: ruff>=0.11.6
|
|
21
|
+
Requires-Dist: streamlit>=1.44.1
|
|
22
|
+
Requires-Dist: watchdog>=6.0.0
|
|
23
|
+
Provides-Extra: test
|
|
24
|
+
Requires-Dist: pyyaml; extra == "test"
|
|
25
|
+
Provides-Extra: feature
|
|
26
|
+
Requires-Dist: logfire; extra == "feature"
|
|
27
|
+
|
|
28
|
+
# AiXplore-tools
|
|
29
|
+
|
|
30
|
+
AiXplore-tools (`axitools` for short) is a Python library to support AI agent development and debugging. It serves two main purposes:
|
|
31
|
+
|
|
32
|
+
1. **Utility Library**: A collection of utility functions and classes for agent projects
|
|
33
|
+
2. **Debugging Tool**: A Streamlit app (`log_view`) for visualizing and debugging agent applications by viewing messages logged by `ObjectLogger`
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## `.venv`
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
# Create a new environment
|
|
40
|
+
uv venv .venv
|
|
41
|
+
source .venv/bin/activate
|
|
42
|
+
|
|
43
|
+
# Add packages
|
|
44
|
+
uv add pydantic-ai
|
|
45
|
+
uv add mcp[cli]
|
|
46
|
+
uv add chainlit
|
|
47
|
+
uv add streamlit
|
|
48
|
+
|
|
49
|
+
# Add langchain
|
|
50
|
+
uv add langchain-chroma
|
|
51
|
+
uv add langchain-ollama
|
|
52
|
+
uv add langchain-openai
|
|
53
|
+
|
|
54
|
+
# Other packages
|
|
55
|
+
uv add colorlog
|
|
56
|
+
uv add pandas
|
|
57
|
+
uv add rich
|
|
58
|
+
uv add ruff
|
|
59
|
+
uv add watchdog
|
|
60
|
+
uv add ipykernel
|
|
61
|
+
|
|
62
|
+
# Install this code as a package
|
|
63
|
+
uv pip install -e .
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
Installing the package from GitHub, you can use `uv add` (prefered)
|
|
69
|
+
```
|
|
70
|
+
uv add https://github.com/your-org/aixtools.git
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
or using the `pip` commamnd
|
|
74
|
+
```
|
|
75
|
+
uv pip install https://github.com/your-org/aixtools.git
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Remember to set up your [`.env` file](#environment-configuration).
|
|
79
|
+
|
|
80
|
+
### Updating
|
|
81
|
+
|
|
82
|
+
This package is in active development and changes often.
|
|
83
|
+
|
|
84
|
+
You'll want to force uv to re-install or update it to the latest commit, even if the version hasn’t changed.
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
uv add --upgrade https://github.com/your-org/aixtools.git
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Example: Creatng a new project
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
# Create a new project
|
|
94
|
+
uv init MyNewProject
|
|
95
|
+
cd MyNewProject
|
|
96
|
+
|
|
97
|
+
# Add a virtual environemnt and activate it
|
|
98
|
+
uv venv .venv
|
|
99
|
+
source .venv/bin/activate
|
|
100
|
+
|
|
101
|
+
# Add this package
|
|
102
|
+
uv add https://github.com/your-org/aixtools.git
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Environment Configuration
|
|
106
|
+
|
|
107
|
+
AIXtools requires specific environment variables to be set for proper operation, especially when working with different model providers.
|
|
108
|
+
|
|
109
|
+
Here is a [template of an `.env`](./.env_template) file you can use as reference.
|
|
110
|
+
|
|
111
|
+
#### Setting Up Environment Variables
|
|
112
|
+
|
|
113
|
+
1. Create a `.env` file in your project root based on the template below:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
# Model family (azure, openai, or ollama)
|
|
117
|
+
MODEL_FAMILY=azure
|
|
118
|
+
VDB_EMBEDDINGS_MODEL_FAMILY=azure
|
|
119
|
+
|
|
120
|
+
MODEL_TIMEOUT=120
|
|
121
|
+
|
|
122
|
+
# Azure OpenAI
|
|
123
|
+
AZURE_OPENAI_ENDPOINT=https://your_endpoint.openai.azure.com
|
|
124
|
+
AZURE_OPENAI_API_VERSION=2024-06-01
|
|
125
|
+
AZURE_OPENAI_API_KEY=your_secret_key
|
|
126
|
+
AZURE_MODEL_NAME=gpt-4o
|
|
127
|
+
AZURE_OPENAI_PROVIDER_ID=azure
|
|
128
|
+
AZURE_VDB_EMBEDDINGS_MODEL_NAME=text-embedding-3-small
|
|
129
|
+
|
|
130
|
+
# OpenAI
|
|
131
|
+
OPENAI_MODEL_NAME=gpt-4.5-preview
|
|
132
|
+
OPENAI_API_KEY=openai_api_key
|
|
133
|
+
OPENAI_VDB_EMBEDDINGS_MODEL_NAME=text-embedding-3-small
|
|
134
|
+
|
|
135
|
+
# Ollama models
|
|
136
|
+
OLLAMA_MODEL_NAME=llama3.2:3b-instruct-fp16
|
|
137
|
+
OLLAMA_LOCAL_URL=http://localhost:11434/v1
|
|
138
|
+
OLLAMA_VDB_EMBEDDINGS_MODEL_NAME=snowflake-arctic-embed2:latest
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
2. Configure the variables according to your needs:
|
|
142
|
+
- Set `MODEL_FAMILY` to your preferred model provider (`azure`, `openai`, or `ollama`)
|
|
143
|
+
- Provide the appropriate API keys and endpoints for your chosen provider
|
|
144
|
+
- Adjust model names and timeouts as needed
|
|
145
|
+
|
|
146
|
+
#### Important Environment Variables
|
|
147
|
+
|
|
148
|
+
| Variable | Description | Required |
|
|
149
|
+
|----------|-------------|----------|
|
|
150
|
+
| `MODEL_FAMILY` | The model provider to use (azure, openai, ollama) | Yes |
|
|
151
|
+
| `MODEL_TIMEOUT` | Timeout in seconds for model requests | Yes |
|
|
152
|
+
| `AZURE_*` | Azure OpenAI configuration (if using Azure) | If MODEL_FAMILY=azure |
|
|
153
|
+
| `OPENAI_*` | OpenAI configuration (if using OpenAI) | If MODEL_FAMILY=openai |
|
|
154
|
+
| `OLLAMA_*` | Ollama configuration (if using Ollama) | If MODEL_FAMILY=ollama |
|
|
155
|
+
|
|
156
|
+
## Debugging tools: `log_view` and `ObjectLogger`
|
|
157
|
+
|
|
158
|
+
The `ObjectLogger` provides a simple logging facility, these logs can then be visualized with `log_view` app.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
### `ObjectLogger`
|
|
162
|
+
|
|
163
|
+
The `ObjectLogger` class allows you to log objects to a file for later analysis. This is particularly useful for debugging agent interactions.
|
|
164
|
+
|
|
165
|
+
`ObjectLogger` simply serializes objects to a pickle file. It first removes unserializeable parts of the objects (e.g. like `async` managers).
|
|
166
|
+
|
|
167
|
+
#### Basic Usage
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from aixtools.utils.log_objects import ObjectLogger
|
|
171
|
+
|
|
172
|
+
# Create a logger as a context manager
|
|
173
|
+
with ObjectLogger() as logger:
|
|
174
|
+
# Log any pickleable object
|
|
175
|
+
logger.log({"message": "Hello, world!"})
|
|
176
|
+
|
|
177
|
+
# Log agent responses or any other objects
|
|
178
|
+
logger.log(agent_response)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Logging Agent Interactions
|
|
182
|
+
|
|
183
|
+
The function `run_agent` logs each node from the agent run, roughtly it looks like this:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
async def run_agent(agent: Agent, prompt: str | list[str]):
|
|
187
|
+
nodes = []
|
|
188
|
+
async with agent.iter(prompt) as agent_run:
|
|
189
|
+
with ObjectLogger(debug=debug) as agent_logger:
|
|
190
|
+
async for node in agent_run:
|
|
191
|
+
agent_logger.log(node)
|
|
192
|
+
nodes.append(node)
|
|
193
|
+
result = agent_run.result
|
|
194
|
+
return result.data, nodes
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Saving Multiple Objects
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from aixtools.utils.log_objects import save_objects_to_logfile
|
|
201
|
+
|
|
202
|
+
# Save a list of objects to a log file
|
|
203
|
+
objects = [obj1, obj2, obj3]
|
|
204
|
+
save_objects_to_logfile(objects)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### log_view App
|
|
208
|
+
|
|
209
|
+
The `log_view` app allows you to visualize and analyze the objects logged by `ObjectLogger`.
|
|
210
|
+
|
|
211
|
+
It is a simple Streamlit app that you can run locally and view the log files.
|
|
212
|
+
|
|
213
|
+
#### Running the App
|
|
214
|
+
|
|
215
|
+
You can run the app using the command-line script installed with the package:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
log_view
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Or specify a custom log directory:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
log_view /path/to/logs
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Features
|
|
228
|
+
|
|
229
|
+
The log_view app provides several features for analyzing logged objects:
|
|
230
|
+
|
|
231
|
+
- **Log File Selection**: Choose from available log files
|
|
232
|
+
- **Filtering**: Filter nodes by text, type, attributes, or regex patterns
|
|
233
|
+
- **Visualization**: Expand/collapse nodes to view details
|
|
234
|
+
- **Export**: Export filtered nodes to JSON
|
|
235
|
+
|
|
236
|
+
#### Example Workflow
|
|
237
|
+
|
|
238
|
+
1. Log agent interactions using `ObjectLogger`
|
|
239
|
+
2. Run the `log_view` app to analyze the logs
|
|
240
|
+
3. Filter and explore the logged objects
|
|
241
|
+
4. Export interesting findings for further analysis
|
|
242
|
+
|
|
243
|
+
## Additional Utilities
|
|
244
|
+
|
|
245
|
+
AIXtools provides several other utilities to support agent development:
|
|
246
|
+
|
|
247
|
+
### PersistedDict
|
|
248
|
+
|
|
249
|
+
A dictionary that persists to a file on disk as JSON or pickle:
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
from aixtools.utils.persisted_dict import PersistedDict
|
|
253
|
+
|
|
254
|
+
# Create a persisted dictionary
|
|
255
|
+
data = PersistedDict("data.json")
|
|
256
|
+
|
|
257
|
+
# Use it like a regular dictionary
|
|
258
|
+
data["key"] = "value" # Automatically saved to disk
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Agent Utilities
|
|
262
|
+
|
|
263
|
+
Functions for creating and running agents with different model providers:
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
from aixtools.agents.agent import get_agent, run_agent
|
|
267
|
+
|
|
268
|
+
# Create an agent with the default model (from MODEL_FAMILY)
|
|
269
|
+
agent = get_agent(system_prompt="You are a helpful assistant.")
|
|
270
|
+
|
|
271
|
+
# Create an agent with a specific model
|
|
272
|
+
from aixtools.agents.agent import get_model_openai
|
|
273
|
+
model = get_model_openai()
|
|
274
|
+
agent = get_agent(system_prompt="You are a helpful assistant.", model=model)
|
|
275
|
+
|
|
276
|
+
# Run the agent
|
|
277
|
+
result, nodes = await run_agent(agent, "Tell me about AI")
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Batch Processing
|
|
281
|
+
|
|
282
|
+
Run multiple agent queries simultaneously:
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
from aixtools.agents.agent_batch import agent_batch, AgentQueryParams
|
|
286
|
+
|
|
287
|
+
# Create query parameters
|
|
288
|
+
query_parameters = [
|
|
289
|
+
AgentQueryParams(prompt="What is the meaning of life"),
|
|
290
|
+
AgentQueryParams(prompt="Who is the prime minister of Canada")
|
|
291
|
+
]
|
|
292
|
+
|
|
293
|
+
# Run queries in batches
|
|
294
|
+
async for result in agent_batch(query_parameters):
|
|
295
|
+
print(result)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Project Structure
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
aixtools/
|
|
302
|
+
├── __init__.py # Package initialization
|
|
303
|
+
├── log_view.py # Entry point for log_view app
|
|
304
|
+
├── agents/ # Agent-related functionality
|
|
305
|
+
│ ├── agent.py # Core agent functions
|
|
306
|
+
│ └── agent_batch.py # Batch processing for agents
|
|
307
|
+
├── log_view/ # Log viewer application
|
|
308
|
+
│ ├── app.py # Main Streamlit application
|
|
309
|
+
│ ├── display.py # Node display utilities
|
|
310
|
+
│ ├── export.py # Export functionality
|
|
311
|
+
│ ├── filters.py # Node filtering
|
|
312
|
+
│ ├── log_utils.py # Log file utilities
|
|
313
|
+
│ └── node_utils.py # Node processing utilities
|
|
314
|
+
└── utils/ # Utility functions and classes
|
|
315
|
+
├── config.py # Configuration utilities
|
|
316
|
+
├── log_objects.py # Object logging functionality
|
|
317
|
+
├── persisted_dict.py # Persistent dictionary
|
|
318
|
+
└── utils.py # General utilities
|
|
319
|
+
|
|
320
|
+
## Logging
|
|
321
|
+
|
|
322
|
+
The logging system is configured using a standard Python `dictConfig` schema. By default, it will look for a `logging.yaml` or `logging.json` file in your project's root directory. You can also specify a custom path using the `LOGGING_CONFIG_PATH` environment variable.
|
|
323
|
+
|
|
324
|
+
If no configuration file is found, a default colorized console logger will be used.
|
|
325
|
+
|
|
326
|
+
### Example `logging.yaml`
|
|
327
|
+
|
|
328
|
+
```yaml
|
|
329
|
+
version: 1
|
|
330
|
+
disable_existing_loggers: false
|
|
331
|
+
formatters:
|
|
332
|
+
default:
|
|
333
|
+
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
334
|
+
color:
|
|
335
|
+
"()": "colorlog.ColoredFormatter"
|
|
336
|
+
"format": "%(log_color)s%(levelname)-8s%(reset)s [%(name)s] %(message)s"
|
|
337
|
+
handlers:
|
|
338
|
+
console:
|
|
339
|
+
class: colorlog.StreamHandler
|
|
340
|
+
formatter: color
|
|
341
|
+
level: DEBUG
|
|
342
|
+
file:
|
|
343
|
+
class: logging.handlers.RotatingFileHandler
|
|
344
|
+
formatter: default
|
|
345
|
+
filename: app.log
|
|
346
|
+
maxBytes: 10485760 # 10MB
|
|
347
|
+
backupCount: 5
|
|
348
|
+
level: INFO
|
|
349
|
+
root:
|
|
350
|
+
handlers: [console, file]
|
|
351
|
+
level: DEBUG
|
|
352
|
+
loggers:
|
|
353
|
+
aixtools:
|
|
354
|
+
level: INFO
|
|
355
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
aixtools/__init__.py,sha256=zQNIT0XqMMo29K4p1s42JSilML8MapSGVrkQFjDXibQ,81
|
|
2
|
+
aixtools/app.py,sha256=JzQ0nrv_bjDQokllIlGHOV0HEb-V8N6k_nGQH-TEsVU,5227
|
|
3
|
+
aixtools/context.py,sha256=XuvSGjG8f-QHBJlI_yCPdjYo4rm_WrswmUE8GjLoRqI,491
|
|
4
|
+
aixtools/a2a/__init__.py,sha256=UGeU-1JoE-QmgT3A_9r4Gzw7WQU2cZr4JxNGqm5ZZrg,191
|
|
5
|
+
aixtools/a2a/app.py,sha256=VQAKJHYJJr5-qJRLXvRgc2pZtH_SPXvB293nJaEDXTw,5071
|
|
6
|
+
aixtools/a2a/utils.py,sha256=EHr3IyyBJn23ni-JcfAf6i3VpQmPs0g1TSnAZazvY_8,4039
|
|
7
|
+
aixtools/agents/__init__.py,sha256=MAW196S2_G7uGqv-VNjvlOETRfuV44WlU1leO7SiR0A,282
|
|
8
|
+
aixtools/agents/agent.py,sha256=E1zu70t53RqIbcLI_R09wUtsiYZR1bTnElCQ5PrsrKw,6127
|
|
9
|
+
aixtools/agents/agent_batch.py,sha256=QHRXh7X1VdzLX9JcgIIvU06E46orhv3R7uJyj9TfIlo,2322
|
|
10
|
+
aixtools/db/__init__.py,sha256=b8vRhme3egV-aUZbAntnOaDkSXB8UT0Xy5oqQhU_z0Q,399
|
|
11
|
+
aixtools/db/database.py,sha256=caWe95GlxZYlxn2ubDmR-_cQUW0ulkpR3BHunKIaOsw,3369
|
|
12
|
+
aixtools/db/vector_db.py,sha256=be4JGyXj3o8VEfy9L6SO1aAoDET_zazMJkYfjlYHTYQ,4133
|
|
13
|
+
aixtools/log_view/__init__.py,sha256=0fWLCq9BMo8GoH3Z5WDgvf0-J2TP0XWqtef0f28SHBA,405
|
|
14
|
+
aixtools/log_view/app.py,sha256=DZp3PUM_iS3DpMHqHfFXVACvbZ9PItbOCNMkDjIOfTc,6595
|
|
15
|
+
aixtools/log_view/display.py,sha256=8ygvtfUjieD8JKov_cnAi5KNMsGoOCE4AeZmDwAa8DU,9971
|
|
16
|
+
aixtools/log_view/export.py,sha256=1apA1jeB94dF1FJiHIWrWbkDBFYqTwJ6s8hmifGm19c,1811
|
|
17
|
+
aixtools/log_view/filters.py,sha256=xbgSzzUnkqHoS_A_p4lRDMFhXqFvXCjwkcIEBQ_L29g,1402
|
|
18
|
+
aixtools/log_view/log_utils.py,sha256=PGUUB039x6w7nOLg_M6Jk1aDIvcjyKP4f3YF5kavQ88,914
|
|
19
|
+
aixtools/log_view/node_summary.py,sha256=EJjnBqdBWI-_bI-4nfTxwaost3mtiufb5cK7T54cfuQ,9299
|
|
20
|
+
aixtools/logfilters/__init__.py,sha256=pTD8ujCqjPWBCeB7yv7lmCtnA2KXOnkIv0HExDagkXs,129
|
|
21
|
+
aixtools/logfilters/context_filter.py,sha256=zR3Bnv3fCqXLeb7bCFTmlnWhC6dFIvUb-u712tOnUPk,2259
|
|
22
|
+
aixtools/logging/__init__.py,sha256=b5oYyGQDUHHxhRtzqKUaQPv8hQeWw54rzDXSV8lDY1w,613
|
|
23
|
+
aixtools/logging/log_objects.py,sha256=hKMLIsWZEw9Q0JT3GCn9mS8O7DJCzsgMZTL7mlMObpM,6828
|
|
24
|
+
aixtools/logging/logging_config.py,sha256=LBUjR5aDUh_G5U2EA2yjzw9IuOZHHUJli1y-TVpj9lA,3267
|
|
25
|
+
aixtools/logging/mcp_log_models.py,sha256=7-H2GJXiiyLhpImuyLLftAGG4skxJal8Swax0ob04MY,3463
|
|
26
|
+
aixtools/logging/mcp_logger.py,sha256=d2I5l4t0d6rQH17w23FpE1IUD8Ax-mSaKfByCH86q4I,6257
|
|
27
|
+
aixtools/logging/model_patch_logging.py,sha256=MY2EvR7ZSctC4hJxNMe8iACeVayUJ2V5In2GAnKdgOo,2880
|
|
28
|
+
aixtools/logging/open_telemetry.py,sha256=fJjF1ou_8GyfNfbyWDQPGK6JAUrUaPwURYPHhXEtDBE,1121
|
|
29
|
+
aixtools/mcp/__init__.py,sha256=tLo2KZ1Ojo-rgEEJBGtZfUw-iOoopWoHDnYQTq3IzfE,163
|
|
30
|
+
aixtools/mcp/example_client.py,sha256=QCFGP3NCNJMOKWjUOnFwjnbJhUSb879IA1ZYmwjRnmc,889
|
|
31
|
+
aixtools/mcp/example_server.py,sha256=1SWCyrLWsAnOa81HC4QbPJo_lBVu0b3SZBWI-qDh1vQ,458
|
|
32
|
+
aixtools/mcp/fast_mcp_log.py,sha256=XYOS406dVjn5YTHyGRsRvVNQ0SKlRObfrKj6EeLFjHg,1057
|
|
33
|
+
aixtools/mcp/faulty_mcp.py,sha256=7wPjw0w0eSKpwuqkIYIRCD9iSGGb5IDQpCgcpMOLBmg,13044
|
|
34
|
+
aixtools/model_patch/model_patch.py,sha256=My1BHp9pIdnEdJ_yXNnwCgrLRJ04g9CDG7-HUfC4IjY,1795
|
|
35
|
+
aixtools/server/__init__.py,sha256=rwPx020YpOzCnrxA80Lc4yLLcIp-Mpe9hNqVO9wDPv0,448
|
|
36
|
+
aixtools/server/app_mounter.py,sha256=0tJ0tC140ezAjnYdlhpLJQjY-TO8NVw7D8LseYCCVY8,3336
|
|
37
|
+
aixtools/server/path.py,sha256=SaIJxvmhJy3kzx5zJ6d4cKP6kKu2wFFciQkOLGTA4gg,3056
|
|
38
|
+
aixtools/server/utils.py,sha256=3kIkwpqvc3KsLr5Ja2aGaQ6xy13UaG6K75s2NJVjj-o,2237
|
|
39
|
+
aixtools/testing/__init__.py,sha256=mlmaAR2gmS4SbsYNCxnIprmFpFp-syjgVUkpUszo3mE,166
|
|
40
|
+
aixtools/testing/aix_test_model.py,sha256=dlI3sdyvmu4fUs_K4-oazs_a7cE6V-gnI6RQ0_fPVxg,5925
|
|
41
|
+
aixtools/testing/mock_tool.py,sha256=4I0LxxSkLhGIKM2YxCP3cnYI8IYJjdKhfwGZ3dioXsM,2465
|
|
42
|
+
aixtools/testing/model_patch_cache.py,sha256=238gKC_gSpR3BkeejhetObOkpOR1l2Iz3A6B_eUTRNc,10158
|
|
43
|
+
aixtools/tools/doctor/__init__.py,sha256=FPwYzC1eJyw8IH0-BP0wgxSprLy6Y_4yXCek7496f2k,64
|
|
44
|
+
aixtools/tools/doctor/tool_doctor.py,sha256=flp00mbFwVI0-Ii_xC4YDW6Vrn-EAExA1TtQkY6cOZE,2583
|
|
45
|
+
aixtools/tools/doctor/tool_recommendation.py,sha256=t-l5bm6kwnXs1NH-ZZVTWhVrEAmWa460M44bi_Bip4g,1463
|
|
46
|
+
aixtools/utils/__init__.py,sha256=xT6almZBQYMfj4h7Hq9QXDHyVXbOOTxqLsmJsxYYnSw,757
|
|
47
|
+
aixtools/utils/config.py,sha256=1_sGqjj9qahu2thdjJUo6RGi6W2b79UB10sefyfZNMs,4146
|
|
48
|
+
aixtools/utils/config_util.py,sha256=3Ya4Qqhj1RJ1qtTTykQ6iayf5uxlpigPXgEJlTi1wn4,2229
|
|
49
|
+
aixtools/utils/enum_with_description.py,sha256=zjSzWxG74eR4x7dpmb74pLTYCWNSMvauHd7_9LpDYIw,1088
|
|
50
|
+
aixtools/utils/persisted_dict.py,sha256=0jQzV7oF-A6Or-HjcU6V7aMXWQL67SOKpULgmtFwAfg,3110
|
|
51
|
+
aixtools/utils/utils.py,sha256=4AkAPPnymYt4faThWz0QYSrAeQVys-l-YO8Kw302CcA,4703
|
|
52
|
+
aixtools/utils/chainlit/cl_agent_show.py,sha256=vaRuowp4BRvhxEr5hw0zHEJ7iaSF_5bo_9BH7pGPPpw,4398
|
|
53
|
+
aixtools/utils/chainlit/cl_utils.py,sha256=fxaxdkcZg6uHdM8uztxdPowg3a2f7VR7B26VPY4t-3c,5738
|
|
54
|
+
aixtools-0.1.0.dist-info/METADATA,sha256=JXfwOXxEysAft3vycIqsZKgYMURZykDdJg7ut5VnU5c,10109
|
|
55
|
+
aixtools-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
56
|
+
aixtools-0.1.0.dist-info/entry_points.txt,sha256=dHoutULEZx7xXSqJrZdViSVjfInJibfLibi2nRXL3SE,56
|
|
57
|
+
aixtools-0.1.0.dist-info/top_level.txt,sha256=wBn-rw9bCtxrR4AYEYgjilNCUVmKY0LWby9Zan2PRJM,9
|
|
58
|
+
aixtools-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aixtools
|