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.
Files changed (57) hide show
  1. agentx_dev-3.0.1/MANIFEST.in +11 -0
  2. {agentx_dev-3.0/agentx_dev.egg-info → agentx_dev-3.0.1}/PKG-INFO +1 -1
  3. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/__init__.py +17 -0
  4. {agentx_dev-3.0 → agentx_dev-3.0.1/agentx_dev.egg-info}/PKG-INFO +1 -1
  5. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev.egg-info/SOURCES.txt +19 -1
  6. agentx_dev-3.0.1/agentx_dev.egg-info/top_level.txt +4 -0
  7. agentx_dev-3.0.1/examples/README.md +279 -0
  8. agentx_dev-3.0.1/examples/async_example.py +160 -0
  9. agentx_dev-3.0.1/examples/async_quickstart.py +81 -0
  10. agentx_dev-3.0.1/examples/auto_features_example.py +275 -0
  11. agentx_dev-3.0.1/examples/caching_example.py +215 -0
  12. agentx_dev-3.0.1/examples/chatbot_example.py +206 -0
  13. agentx_dev-3.0.1/examples/complete_example.py +339 -0
  14. agentx_dev-3.0.1/examples/concurrent_example.py +286 -0
  15. agentx_dev-3.0.1/examples/concurrent_tool_example.py +303 -0
  16. agentx_dev-3.0.1/examples/file_agent_demo.py +302 -0
  17. agentx_dev-3.0.1/examples/function_calling_demo.py +211 -0
  18. agentx_dev-3.0.1/examples/mcp_demo.py +308 -0
  19. agentx_dev-3.0.1/examples/observability_example.py +322 -0
  20. agentx_dev-3.0.1/examples/orchestration_demo.py +440 -0
  21. agentx_dev-3.0.1/examples/planner_example.py +93 -0
  22. agentx_dev-3.0.1/examples/supervisor_codebase_analysis_demo.py +238 -0
  23. agentx_dev-3.0.1/examples/supervisor_example.py +97 -0
  24. agentx_dev-3.0.1/examples/sync_quickstart.py +75 -0
  25. {agentx_dev-3.0 → agentx_dev-3.0.1}/pyproject.toml +1 -1
  26. agentx_dev-3.0/MANIFEST.in +0 -5
  27. agentx_dev-3.0/agentx_dev.egg-info/top_level.txt +0 -2
  28. {agentx_dev-3.0 → agentx_dev-3.0.1}/AGENTX.md +0 -0
  29. {agentx_dev-3.0 → agentx_dev-3.0.1}/LICENSE +0 -0
  30. {agentx_dev-3.0 → agentx_dev-3.0.1}/README.md +0 -0
  31. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Agents/Agent.py +0 -0
  32. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Agents/__init__.py +0 -0
  33. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/AsyncTools.py +0 -0
  34. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/AutoSetup.py +0 -0
  35. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Cache.py +0 -0
  36. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/ChatModel.py +0 -0
  37. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Config.py +0 -0
  38. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/DefaultTools.py +0 -0
  39. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Loader.py +0 -0
  40. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/MCP.py +0 -0
  41. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Memory.py +0 -0
  42. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Observability.py +0 -0
  43. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Planner.py +0 -0
  44. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/AgentRun.py +0 -0
  45. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/AsyncAgentRun.py +0 -0
  46. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/__init__.py +0 -0
  47. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Runner/promptTemplate.yaml +0 -0
  48. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Session.py +0 -0
  49. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Streaming.py +0 -0
  50. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Supervisor.py +0 -0
  51. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/Tools.py +0 -0
  52. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/WebTools.py +0 -0
  53. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/resources/__init__.py +0 -0
  54. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev/resources/promptTemplate.yaml +0 -0
  55. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev.egg-info/dependency_links.txt +0 -0
  56. {agentx_dev-3.0 → agentx_dev-3.0.1}/agentx_dev.egg-info/requires.txt +0 -0
  57. {agentx_dev-3.0 → agentx_dev-3.0.1}/setup.cfg +0 -0
@@ -0,0 +1,11 @@
1
+ graft agentx_dev
2
+ graft examples
3
+ include AGENTX.md
4
+ include README.md
5
+ include LICENSE
6
+ prune tests
7
+ prune examples/_sandbox
8
+ prune examples/_sandbox_mcp
9
+ global-exclude __pycache__
10
+ global-exclude *.pyc
11
+ global-exclude *.pyo
@@ -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,4 @@
1
+ agentx_dev
2
+ dist
3
+ examples
4
+ test_dl
@@ -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())