agentx-dev 3.0__tar.gz → 3.0.1__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.
- agentx_dev-3.0.1/MANIFEST.in +11 -0
- {agentx_dev-3.0/agentx_dev.egg-info → agentx_dev-3.0.1}/PKG-INFO +1 -1
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/__init__.py +17 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1/agentx_dev.egg-info}/PKG-INFO +1 -1
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev.egg-info/SOURCES.txt +19 -1
- agentx_dev-3.0.1/agentx_dev.egg-info/top_level.txt +4 -0
- agentx_dev-3.0.1/examples/README.md +279 -0
- agentx_dev-3.0.1/examples/async_example.py +160 -0
- agentx_dev-3.0.1/examples/async_quickstart.py +81 -0
- agentx_dev-3.0.1/examples/auto_features_example.py +275 -0
- agentx_dev-3.0.1/examples/caching_example.py +215 -0
- agentx_dev-3.0.1/examples/chatbot_example.py +206 -0
- agentx_dev-3.0.1/examples/complete_example.py +339 -0
- agentx_dev-3.0.1/examples/concurrent_example.py +286 -0
- agentx_dev-3.0.1/examples/concurrent_tool_example.py +303 -0
- agentx_dev-3.0.1/examples/file_agent_demo.py +302 -0
- agentx_dev-3.0.1/examples/function_calling_demo.py +211 -0
- agentx_dev-3.0.1/examples/mcp_demo.py +308 -0
- agentx_dev-3.0.1/examples/observability_example.py +322 -0
- agentx_dev-3.0.1/examples/orchestration_demo.py +440 -0
- agentx_dev-3.0.1/examples/planner_example.py +93 -0
- agentx_dev-3.0.1/examples/supervisor_codebase_analysis_demo.py +238 -0
- agentx_dev-3.0.1/examples/supervisor_example.py +97 -0
- agentx_dev-3.0.1/examples/sync_quickstart.py +75 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/pyproject.toml +1 -1
- agentx_dev-3.0/MANIFEST.in +0 -5
- agentx_dev-3.0/agentx_dev.egg-info/top_level.txt +0 -2
- {agentx_dev-3.0 → agentx_dev-3.0.1}/AGENTX.md +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/LICENSE +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/README.md +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Agents/Agent.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Agents/__init__.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/AsyncTools.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/AutoSetup.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Cache.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/ChatModel.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Config.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/DefaultTools.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Loader.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/MCP.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Memory.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Observability.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Planner.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/AgentRun.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/AsyncAgentRun.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/__init__.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/promptTemplate.yaml +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Session.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Streaming.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Supervisor.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Tools.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/WebTools.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/resources/__init__.py +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/resources/promptTemplate.yaml +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev.egg-info/dependency_links.txt +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev.egg-info/requires.txt +0 -0
- {agentx_dev-3.0 → agentx_dev-3.0.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-dev
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: A lightweight LLM agent framework with multi-agent orchestration (Supervisor + dynamic specialist spawning), permission-gated default tools, MCP integration, and prompt-template presets.
|
|
5
5
|
Author-email: Bruce-Arhin Shadrach <brucearhin098@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -40,6 +40,11 @@ from .Loader import (
|
|
|
40
40
|
from .DefaultTools import DefaultTools, Permissions, DEFAULT_PERMISSIONS_PATH, mint_session_dir
|
|
41
41
|
from .Session import Session
|
|
42
42
|
from .WebTools import web_fetch_tool, web_search_tool
|
|
43
|
+
from .Supervisor import (
|
|
44
|
+
Supervisor, AsyncSupervisor,
|
|
45
|
+
SpawnConfig, SpawnRequest,
|
|
46
|
+
SupervisorResult, SubtaskResult,
|
|
47
|
+
)
|
|
43
48
|
|
|
44
49
|
# MCP is an optional dependency — only re-export the names if the module imports cleanly.
|
|
45
50
|
try:
|
|
@@ -145,6 +150,18 @@ __all__ = [
|
|
|
145
150
|
|
|
146
151
|
# Session persistence
|
|
147
152
|
"Session",
|
|
153
|
+
|
|
154
|
+
# Web tools (optional plug-ins, not in DefaultTools)
|
|
155
|
+
"web_search_tool",
|
|
156
|
+
"web_fetch_tool",
|
|
157
|
+
|
|
158
|
+
# Multi-agent orchestration
|
|
159
|
+
"Supervisor",
|
|
160
|
+
"AsyncSupervisor",
|
|
161
|
+
"SpawnConfig",
|
|
162
|
+
"SpawnRequest",
|
|
163
|
+
"SupervisorResult",
|
|
164
|
+
"SubtaskResult",
|
|
148
165
|
]
|
|
149
166
|
|
|
150
167
|
if _MCP_AVAILABLE:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-dev
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: A lightweight LLM agent framework with multi-agent orchestration (Supervisor + dynamic specialist spawning), permission-gated default tools, MCP integration, and prompt-template presets.
|
|
5
5
|
Author-email: Bruce-Arhin Shadrach <brucearhin098@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -32,4 +32,22 @@ agentx_dev/Runner/AsyncAgentRun.py
|
|
|
32
32
|
agentx_dev/Runner/__init__.py
|
|
33
33
|
agentx_dev/Runner/promptTemplate.yaml
|
|
34
34
|
agentx_dev/resources/__init__.py
|
|
35
|
-
agentx_dev/resources/promptTemplate.yaml
|
|
35
|
+
agentx_dev/resources/promptTemplate.yaml
|
|
36
|
+
examples/README.md
|
|
37
|
+
examples/async_example.py
|
|
38
|
+
examples/async_quickstart.py
|
|
39
|
+
examples/auto_features_example.py
|
|
40
|
+
examples/caching_example.py
|
|
41
|
+
examples/chatbot_example.py
|
|
42
|
+
examples/complete_example.py
|
|
43
|
+
examples/concurrent_example.py
|
|
44
|
+
examples/concurrent_tool_example.py
|
|
45
|
+
examples/file_agent_demo.py
|
|
46
|
+
examples/function_calling_demo.py
|
|
47
|
+
examples/mcp_demo.py
|
|
48
|
+
examples/observability_example.py
|
|
49
|
+
examples/orchestration_demo.py
|
|
50
|
+
examples/planner_example.py
|
|
51
|
+
examples/supervisor_codebase_analysis_demo.py
|
|
52
|
+
examples/supervisor_example.py
|
|
53
|
+
examples/sync_quickstart.py
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# AgentX Examples
|
|
2
|
+
|
|
3
|
+
This directory contains practical examples demonstrating the enhanced features of AgentX framework.
|
|
4
|
+
|
|
5
|
+
## Examples Overview
|
|
6
|
+
|
|
7
|
+
### 1. `async_example.py` - Async Tool Execution
|
|
8
|
+
**What it demonstrates:**
|
|
9
|
+
- Creating async tools with `AsyncStandardTool` and `AsyncStructuredTool`
|
|
10
|
+
- Concurrent execution of multiple tools
|
|
11
|
+
- Using `AsyncAgentRunner`
|
|
12
|
+
- Mixing sync and async tools
|
|
13
|
+
|
|
14
|
+
**Run it:**
|
|
15
|
+
```bash
|
|
16
|
+
python async_example.py
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Key takeaways:**
|
|
20
|
+
- Async tools enable concurrent I/O operations
|
|
21
|
+
- Significant performance improvements for API calls
|
|
22
|
+
- Backward compatible with sync tools
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
### 2. `caching_example.py` - Tool Result Caching
|
|
27
|
+
**What it demonstrates:**
|
|
28
|
+
- `InMemoryCache` for fast caching with TTL
|
|
29
|
+
- `LRUCache` for capacity-limited caching
|
|
30
|
+
- `FileCache` for persistent caching
|
|
31
|
+
- `@cached_tool` decorator for automatic caching
|
|
32
|
+
- Cache management operations
|
|
33
|
+
|
|
34
|
+
**Run it:**
|
|
35
|
+
```bash
|
|
36
|
+
python caching_example.py
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Key takeaways:**
|
|
40
|
+
- Caching avoids redundant expensive operations
|
|
41
|
+
- Different cache types for different use cases
|
|
42
|
+
- TTL support for automatic expiration
|
|
43
|
+
- Decorator makes caching transparent
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### 3. `observability_example.py` - Monitoring & Metrics
|
|
48
|
+
**What it demonstrates:**
|
|
49
|
+
- Setting up observability hooks
|
|
50
|
+
- `ConsoleHook` for colored console output
|
|
51
|
+
- `MetricsHook` for performance tracking
|
|
52
|
+
- `FileHook` for JSON logging
|
|
53
|
+
- `CallbackHook` for custom processing
|
|
54
|
+
- `@track_tool_call` decorator
|
|
55
|
+
|
|
56
|
+
**Run it:**
|
|
57
|
+
```bash
|
|
58
|
+
python observability_example.py
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Key takeaways:**
|
|
62
|
+
- Monitor every step of agent execution
|
|
63
|
+
- Collect performance metrics automatically
|
|
64
|
+
- Custom callbacks for integration
|
|
65
|
+
- Zero-config observability
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### 4. `complete_example.py` - All Features Together
|
|
70
|
+
**What it demonstrates:**
|
|
71
|
+
- Complete multi-turn conversation setup
|
|
72
|
+
- All enhanced features working together
|
|
73
|
+
- Real-world usage patterns
|
|
74
|
+
- Best practices
|
|
75
|
+
|
|
76
|
+
**Run it:**
|
|
77
|
+
```bash
|
|
78
|
+
python complete_example.py
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Key takeaways:**
|
|
82
|
+
- How features integrate seamlessly
|
|
83
|
+
- Production-ready setup
|
|
84
|
+
- Memory + Caching + Observability + Async
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Quick Start
|
|
89
|
+
|
|
90
|
+
### Basic Example (No API Key Needed)
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# Run any example without OpenAI API
|
|
94
|
+
python async_example.py
|
|
95
|
+
python caching_example.py
|
|
96
|
+
python observability_example.py
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
These examples demonstrate the features without requiring an OpenAI API key.
|
|
100
|
+
|
|
101
|
+
### With OpenAI API
|
|
102
|
+
|
|
103
|
+
To use the actual agent functionality:
|
|
104
|
+
|
|
105
|
+
1. Set your API key:
|
|
106
|
+
```bash
|
|
107
|
+
export OPENAI_API_KEY='your-key-here'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
2. Uncomment the agent creation code in examples
|
|
111
|
+
|
|
112
|
+
3. Run the example
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Learning Path
|
|
117
|
+
|
|
118
|
+
**Recommended order for learning:**
|
|
119
|
+
|
|
120
|
+
1. **Start with caching** (`caching_example.py`)
|
|
121
|
+
- Easiest to understand
|
|
122
|
+
- Immediate performance benefits
|
|
123
|
+
- No async complexity
|
|
124
|
+
|
|
125
|
+
2. **Add observability** (`observability_example.py`)
|
|
126
|
+
- See what's happening inside agents
|
|
127
|
+
- Learn event tracking
|
|
128
|
+
- Understand performance metrics
|
|
129
|
+
|
|
130
|
+
3. **Try async tools** (`async_example.py`)
|
|
131
|
+
- Understand async benefits
|
|
132
|
+
- See concurrent execution
|
|
133
|
+
- Compare performance
|
|
134
|
+
|
|
135
|
+
4. **Complete example** (`complete_example.py`)
|
|
136
|
+
- See everything together
|
|
137
|
+
- Real-world patterns
|
|
138
|
+
- Production setup
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Example Output
|
|
143
|
+
|
|
144
|
+
### Caching Performance
|
|
145
|
+
```
|
|
146
|
+
First call (cache miss):
|
|
147
|
+
[EXECUTING] expensive_operation('test query')
|
|
148
|
+
Result: Result for: test query
|
|
149
|
+
Time: 2.01s
|
|
150
|
+
|
|
151
|
+
Second call (cache hit):
|
|
152
|
+
Result: Result for: test query
|
|
153
|
+
Time: 0.00s
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Concurrent Execution
|
|
157
|
+
```
|
|
158
|
+
Executing 5 tools concurrently...
|
|
159
|
+
Fetching weather for New York...
|
|
160
|
+
Fetching weather for Los Angeles...
|
|
161
|
+
Searching for 'AI news'...
|
|
162
|
+
|
|
163
|
+
Completed in 1.05 seconds
|
|
164
|
+
(vs 3+ seconds sequentially)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Observability Output
|
|
168
|
+
```
|
|
169
|
+
[tool.call.start]
|
|
170
|
+
[tool.call.complete] (123.45ms)
|
|
171
|
+
[llm.call.start]
|
|
172
|
+
[llm.call.complete] (456.78ms)
|
|
173
|
+
|
|
174
|
+
Performance Metrics:
|
|
175
|
+
tool.call.complete: 5 calls, avg 120ms
|
|
176
|
+
llm.call.complete: 3 calls, avg 450ms
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Common Patterns
|
|
182
|
+
|
|
183
|
+
### Pattern 1: Cached Async Tool
|
|
184
|
+
```python
|
|
185
|
+
from agentx_dev import AsyncStandardTool, InMemoryCache, cached_tool
|
|
186
|
+
|
|
187
|
+
cache = InMemoryCache(default_ttl=300)
|
|
188
|
+
|
|
189
|
+
@cached_tool(cache, ttl=60)
|
|
190
|
+
async def api_call(query: str) -> str:
|
|
191
|
+
return await fetch_from_api(query)
|
|
192
|
+
|
|
193
|
+
tool = AsyncStandardTool(func=api_call, name="api")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Pattern 2: Monitored Agent
|
|
197
|
+
```python
|
|
198
|
+
from agentx_dev import observability, ConsoleHook, MetricsHook
|
|
199
|
+
|
|
200
|
+
observability.add_hook(ConsoleHook(verbose=True))
|
|
201
|
+
metrics = MetricsHook()
|
|
202
|
+
observability.add_hook(metrics)
|
|
203
|
+
|
|
204
|
+
# Use agent - events auto-tracked
|
|
205
|
+
response = agent.Initialize("query")
|
|
206
|
+
|
|
207
|
+
# Get metrics
|
|
208
|
+
print(metrics.get_summary())
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Pattern 3: Memory-Managed Conversation
|
|
212
|
+
```python
|
|
213
|
+
from agentx_dev import TokenLimitedMemory
|
|
214
|
+
|
|
215
|
+
memory = TokenLimitedMemory(max_tokens=4000)
|
|
216
|
+
|
|
217
|
+
for user_query in conversation:
|
|
218
|
+
response = agent.Initialize(
|
|
219
|
+
user_query,
|
|
220
|
+
ChatHistory=memory.get_messages()
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
memory.add_message("user", user_query)
|
|
224
|
+
memory.add_message("assistant", response.content)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Troubleshooting
|
|
230
|
+
|
|
231
|
+
### Import Errors
|
|
232
|
+
```python
|
|
233
|
+
# Make sure AgentX is installed
|
|
234
|
+
pip install agentx-dev
|
|
235
|
+
|
|
236
|
+
# Or install in development mode
|
|
237
|
+
pip install -e .
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### OpenAI API Errors
|
|
241
|
+
```python
|
|
242
|
+
# Set API key
|
|
243
|
+
import os
|
|
244
|
+
os.environ['OPENAI_API_KEY'] = 'your-key'
|
|
245
|
+
|
|
246
|
+
# Or pass directly
|
|
247
|
+
from agentx_dev import GPT
|
|
248
|
+
chat_model = GPT(api_key='your-key')
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Async Errors
|
|
252
|
+
```python
|
|
253
|
+
# Run async functions with asyncio
|
|
254
|
+
import asyncio
|
|
255
|
+
|
|
256
|
+
async def main():
|
|
257
|
+
result = await async_agent.Initialize("query")
|
|
258
|
+
|
|
259
|
+
asyncio.run(main())
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Next Steps
|
|
265
|
+
|
|
266
|
+
After running these examples:
|
|
267
|
+
|
|
268
|
+
1. Read `ENHANCEMENTS.md` for detailed documentation
|
|
269
|
+
2. Check `ENHANCEMENT_SUMMARY.md` for overview
|
|
270
|
+
3. Explore the source code in `agentx_dev/`
|
|
271
|
+
4. Build your own agent with these features!
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Questions?
|
|
276
|
+
|
|
277
|
+
- **Documentation**: See `ENHANCEMENTS.md`
|
|
278
|
+
- **Issues**: https://github.com/shadrach098/Bruce_framework/issues
|
|
279
|
+
- **Source**: https://github.com/shadrach098/Bruce_framework
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example: Async Tool Execution with AgentX
|
|
3
|
+
|
|
4
|
+
This example demonstrates how to use async tools for concurrent execution,
|
|
5
|
+
which is particularly useful for I/O-bound operations like API calls.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
from agentx_dev import (
|
|
10
|
+
AsyncAgentRunner, AsyncStandardTool, AsyncStructuredTool,
|
|
11
|
+
AgentType, GPT, execute_tools_concurrently
|
|
12
|
+
)
|
|
13
|
+
from pydantic import BaseModel
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Example 1: Async Standard Tool
|
|
17
|
+
async def fetch_weather(location: str) -> str:
|
|
18
|
+
"""Simulate fetching weather from an API."""
|
|
19
|
+
print(f"Fetching weather for {location}...")
|
|
20
|
+
await asyncio.sleep(1) # Simulate API delay
|
|
21
|
+
return f"Weather in {location}: Sunny, 72°F"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Example 2: Async Structured Tool
|
|
25
|
+
class SearchArgs(BaseModel):
|
|
26
|
+
query: str
|
|
27
|
+
limit: int = 10
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def web_search(query: str, limit: int = 10) -> str:
|
|
31
|
+
"""Simulate web search API call."""
|
|
32
|
+
print(f"Searching for '{query}' (limit: {limit})...")
|
|
33
|
+
await asyncio.sleep(0.5) # Simulate API delay
|
|
34
|
+
return f"Found {limit} results for query: '{query}'"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Example 3: Multiple concurrent tool calls
|
|
38
|
+
async def concurrent_execution_demo():
|
|
39
|
+
"""Demonstrate executing multiple tools concurrently."""
|
|
40
|
+
print("=== Concurrent Tool Execution Demo ===\n")
|
|
41
|
+
|
|
42
|
+
# Create async tools
|
|
43
|
+
weather_tool = AsyncStandardTool(
|
|
44
|
+
func=fetch_weather,
|
|
45
|
+
name="weather",
|
|
46
|
+
description="Get current weather for a location"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
search_tool = AsyncStructuredTool(
|
|
50
|
+
func=web_search,
|
|
51
|
+
args_schema=SearchArgs,
|
|
52
|
+
name="search",
|
|
53
|
+
description="Search the web for information"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Define tools to execute concurrently
|
|
57
|
+
tools_to_run = [
|
|
58
|
+
{'tool': weather_tool, 'args': {'input': 'New York'}},
|
|
59
|
+
{'tool': weather_tool, 'args': {'input': 'Los Angeles'}},
|
|
60
|
+
{'tool': weather_tool, 'args': {'input': 'Chicago'}},
|
|
61
|
+
{'tool': search_tool, 'args': {'query': 'AI news', 'limit': 5}},
|
|
62
|
+
{'tool': search_tool, 'args': {'query': 'Python tutorials', 'limit': 3}}
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
# Execute all tools concurrently
|
|
66
|
+
print("Executing 5 tools concurrently...")
|
|
67
|
+
start_time = asyncio.get_event_loop().time()
|
|
68
|
+
|
|
69
|
+
results = await execute_tools_concurrently(tools_to_run)
|
|
70
|
+
|
|
71
|
+
end_time = asyncio.get_event_loop().time()
|
|
72
|
+
print(f"\nCompleted in {end_time - start_time:.2f} seconds\n")
|
|
73
|
+
|
|
74
|
+
# Display results
|
|
75
|
+
for i, result in enumerate(results):
|
|
76
|
+
print(f"Result {i+1}: {result}")
|
|
77
|
+
|
|
78
|
+
print("\n" + "="*50 + "\n")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# Example 4: Using AsyncAgentRunner
|
|
82
|
+
async def agent_runner_demo():
|
|
83
|
+
"""Demonstrate AsyncAgentRunner with async tools."""
|
|
84
|
+
print("=== AsyncAgentRunner Demo ===\n")
|
|
85
|
+
|
|
86
|
+
# Create tools
|
|
87
|
+
weather_tool = AsyncStandardTool(
|
|
88
|
+
func=fetch_weather,
|
|
89
|
+
name="weather",
|
|
90
|
+
description="Get current weather for a location"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
search_tool = AsyncStructuredTool(
|
|
94
|
+
func=web_search,
|
|
95
|
+
args_schema=SearchArgs,
|
|
96
|
+
name="search",
|
|
97
|
+
description="Search the web for information"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Create chat model (requires OpenAI API key)
|
|
101
|
+
# Uncomment and add your API key to run this example
|
|
102
|
+
# chat_model = GPT(model="gpt-4", api_key="your-api-key-here")
|
|
103
|
+
|
|
104
|
+
# For demo purposes, we'll skip the actual agent run
|
|
105
|
+
print("To run AsyncAgentRunner:")
|
|
106
|
+
print("1. Set your OpenAI API key")
|
|
107
|
+
print("2. Uncomment the agent creation code below\n")
|
|
108
|
+
|
|
109
|
+
# async_agent = AsyncAgentRunner(
|
|
110
|
+
# model=chat_model,
|
|
111
|
+
# Agent=AgentType.ReAct,
|
|
112
|
+
# tools=[weather_tool, search_tool],
|
|
113
|
+
# max_iterations=4
|
|
114
|
+
# )
|
|
115
|
+
#
|
|
116
|
+
# response = await async_agent.Initialize(
|
|
117
|
+
# "What's the weather in NYC and find recent AI news?"
|
|
118
|
+
# )
|
|
119
|
+
#
|
|
120
|
+
# print(f"Agent Response: {response.content}")
|
|
121
|
+
# print(f"Tool Calls Made: {len(response.tool_calls)}")
|
|
122
|
+
|
|
123
|
+
print("\n" + "="*50 + "\n")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# Example 5: Mixing sync and async tools
|
|
127
|
+
async def mixed_tools_demo():
|
|
128
|
+
"""Demonstrate using both sync and async tools together."""
|
|
129
|
+
print("=== Mixed Sync/Async Tools Demo ===\n")
|
|
130
|
+
|
|
131
|
+
# Async tool
|
|
132
|
+
async def async_calculation(x: int, y: int) -> int:
|
|
133
|
+
"""Async calculation (simulating async operation)."""
|
|
134
|
+
await asyncio.sleep(0.1)
|
|
135
|
+
return x * y
|
|
136
|
+
|
|
137
|
+
# Note: In AsyncAgentRunner, sync tools still work
|
|
138
|
+
# They're just not executed concurrently
|
|
139
|
+
print("AsyncAgentRunner supports both sync and async tools.")
|
|
140
|
+
print("Async tools are executed with 'await', sync tools run normally.\n")
|
|
141
|
+
|
|
142
|
+
print("="*50 + "\n")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
async def main():
|
|
146
|
+
"""Run all examples."""
|
|
147
|
+
print("\n" + "="*50)
|
|
148
|
+
print("AgentX Async Tools Examples")
|
|
149
|
+
print("="*50 + "\n")
|
|
150
|
+
|
|
151
|
+
# Run demos
|
|
152
|
+
await concurrent_execution_demo()
|
|
153
|
+
await agent_runner_demo()
|
|
154
|
+
await mixed_tools_demo()
|
|
155
|
+
|
|
156
|
+
print("All examples completed!\n")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Async AsyncAgentRunner quickstart — concurrent tool execution + non-blocking LLM calls.
|
|
3
|
+
|
|
4
|
+
The LLM call now uses `await model.async_initialize()` so the event loop
|
|
5
|
+
is no longer blocked. Claude uses native AsyncAnthropic; GPT runs the sync
|
|
6
|
+
client in a thread pool automatically.
|
|
7
|
+
|
|
8
|
+
Run:
|
|
9
|
+
export OPENAI_API_KEY=sk-...
|
|
10
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
11
|
+
python examples/async_quickstart.py
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import asyncio
|
|
15
|
+
from pydantic import BaseModel
|
|
16
|
+
from agentx_dev import AsyncAgentRunner, AgentType, GPT, Claude
|
|
17
|
+
from agentx_dev.AsyncTools import AsyncStandardTool, AsyncStructuredTool
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# --- Define async tools (I/O-bound work) ---
|
|
21
|
+
|
|
22
|
+
class SearchArgs(BaseModel):
|
|
23
|
+
query: str
|
|
24
|
+
limit: int = 5
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
async def web_search(query: str, limit: int = 5) -> str:
|
|
28
|
+
"""Async web search (simulated)."""
|
|
29
|
+
await asyncio.sleep(0.4) # simulated network call
|
|
30
|
+
return f"Found {limit} results for '{query}'"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def fetch_weather(city: str) -> str:
|
|
34
|
+
"""Async weather fetch (simulated)."""
|
|
35
|
+
await asyncio.sleep(0.3)
|
|
36
|
+
return f"{city}: 19°C, light rain"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
search_tool = AsyncStructuredTool(
|
|
40
|
+
func=web_search,
|
|
41
|
+
args_schema=SearchArgs,
|
|
42
|
+
name="search",
|
|
43
|
+
description="Search the web for information.",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
weather_tool = AsyncStandardTool(
|
|
47
|
+
func=fetch_weather,
|
|
48
|
+
name="weather",
|
|
49
|
+
description="Get current weather for a city.",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async def main():
|
|
54
|
+
# Pick a model — Claude uses native async, GPT runs in a thread pool
|
|
55
|
+
model = Claude(model="claude-sonnet-4-6", max_tokens=2048)
|
|
56
|
+
# model = GPT(model="gpt-4o")
|
|
57
|
+
|
|
58
|
+
runner = AsyncAgentRunner(
|
|
59
|
+
model=model,
|
|
60
|
+
Agent=AgentType.ReAct,
|
|
61
|
+
tools=[search_tool, weather_tool],
|
|
62
|
+
max_iterations=6,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# First call
|
|
66
|
+
r1 = await runner.Initialize(
|
|
67
|
+
"What's the weather in Berlin and search for recent AI news?"
|
|
68
|
+
)
|
|
69
|
+
print("Answer 1:", r1.content)
|
|
70
|
+
print("Tool calls:", [tc.name for tc in r1.tool_calls])
|
|
71
|
+
|
|
72
|
+
# Reusing the same runner now works correctly
|
|
73
|
+
r2 = await runner.Initialize("Search for python tutorials")
|
|
74
|
+
print("\nAnswer 2:", r2.content)
|
|
75
|
+
|
|
76
|
+
# Returned history is no longer None
|
|
77
|
+
print(f"\nHistory length: {len(r2.history)} messages")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == "__main__":
|
|
81
|
+
asyncio.run(main())
|