Skip to content

Commit c37fb07

Browse files
Enhance TinyAgent with Subagent Tools and Anthropic Prompt Caching
This commit introduces a revolutionary subagent system for TinyAgent, enabling parallel task execution with context isolation. Key features include specialized subagents for various tasks, a comprehensive configuration system, and automatic resource management. Additionally, the Anthropic prompt caching mechanism is integrated, optimizing API costs by caching large messages for Claude models. Documentation and examples are updated to reflect these enhancements, providing users with clear guidance on utilizing the new features effectively.
1 parent 670f9ab commit c37fb07

11 files changed

Lines changed: 858 additions & 52 deletions

CHANGELOG.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- **🚀 Subagent Tools System** - Revolutionary parallel task execution with clean context isolation
12+
- `tinyagent.tools.subagent` - Complete subagent toolkit for creating specialized AI workers
13+
- `SubagentConfig` - Comprehensive configuration system with parent agent inheritance
14+
- `SubagentContext` - Context management with automatic resource cleanup and execution tracking
15+
- `ContextManager` - Global context manager with automatic resource lifecycle management
16+
- Factory functions for specialized subagents: `create_research_subagent`, `create_coding_subagent`, `create_analysis_subagent`, `create_writing_subagent`, `create_planning_subagent`
17+
- `create_general_subagent` - General-purpose subagent with Python/shell execution capabilities
18+
- Automatic parent agent parameter inheritance (model, API keys, callbacks, logging, etc.)
19+
- Custom agent factory support for maximum flexibility and extensibility
20+
1121
- **Anthropic Prompt Caching** - Basic caching for Claude models to reduce API costs
1222
- `anthropic_prompt_cache()` - Cache callback for Claude-3 and Claude-4 models
1323
- `AnthropicPromptCacheCallback` - Core callback class for cache control
@@ -17,17 +27,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1727

1828
### Enhanced
1929
- **Hook System** - Added Anthropic prompt cache integration following TinyAgent's callback patterns
30+
- **Architecture** - Revolutionary subagent system with context isolation and resource management
2031
- **Documentation** - Updated README with Anthropic caching usage examples
2132
- **Examples** - Added Anthropic prompt cache example demonstrating basic usage
2233

2334
### Technical Details
35+
36+
#### Subagent System Architecture
37+
- **SubagentConfig** - Dataclass-based configuration with automatic parameter inheritance from parent agents
38+
- **SubagentContext** - Complete execution context with metadata tracking, resource management, and cleanup callbacks
39+
- **ContextManager** - Singleton manager with periodic cleanup, stale context detection, and async context management
40+
- **Agent Factory Pattern** - Pluggable agent creation with support for TinyAgent, TinyCodeAgent, and custom agent factories
41+
- **Resource Lifecycle** - Automatic resource cleanup with context managers and async cleanup callbacks
42+
- **Hook Integration** - Full integration with TinyAgent's callback system including LoggingManager, token tracking, and UI callbacks
43+
- **Parameter Inheritance** - Intelligent parameter extraction from parent agents with selective overrides
44+
- **Execution Isolation** - Complete context separation between subagents with independent conversation histories
45+
- **Timeout Management** - Configurable timeouts with automatic context cleanup on timeout
46+
- **Working Directory Management** - Per-subagent working directory control with environment variable support
47+
48+
#### Anthropic Prompt Caching
2449
- **AnthropicPromptCacheCallback** - Lightweight callback that adds `cache_control: {"type": "ephemeral"}` to large messages
2550
- **Model Support** - Supports all Claude-3 and Claude-4 models using pattern matching ("claude-3", "claude-4")
2651
- **Content Detection** - Uses 4000+ character threshold (~1000 tokens) to determine when to add caching
2752
- **Message Format** - Converts string content to structured format when adding cache control
2853
- **Case Insensitive** - Model detection works regardless of model name casing
2954

3055
### Benefits
56+
57+
#### Subagent System Benefits
58+
- **🔄 Parallel Processing** - Execute multiple specialized tasks concurrently with complete isolation
59+
- **🧠 Specialized Intelligence** - Create domain-specific agents (research, coding, analysis, writing, planning)
60+
- **🛡️ Resource Safety** - Automatic cleanup prevents memory leaks and resource exhaustion
61+
- **🔗 Seamless Integration** - Inherits parent agent configuration (API keys, models, callbacks) automatically
62+
- **🎯 Context Isolation** - Each subagent has independent conversation history and execution context
63+
- **⚙️ Extensible Architecture** - Custom agent factories allow integration with any agent implementation
64+
- **📊 Execution Tracking** - Complete metadata tracking with execution logs, duration, and resource usage
65+
- **🔧 Developer Experience** - Simple factory functions with sensible defaults and comprehensive configuration options
66+
- **🏗️ Production Ready** - Timeout management, error handling, and automatic context cleanup for enterprise use
67+
68+
#### Anthropic Prompt Caching Benefits
3169
- **Cost Optimization** - Automatic caching for substantial messages reduces API costs
3270
- **Developer Experience** - Simple one-line setup: `agent.add_callback(anthropic_prompt_cache())`
3371
- **Zero Configuration** - Works out of the box with sensible defaults
@@ -55,6 +93,81 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5593

5694
## Migration Guide
5795

96+
### Using the New Subagent System
97+
98+
The subagent system revolutionizes how you can break down complex tasks into specialized, parallel executions:
99+
100+
**Basic Subagent Usage:**
101+
```python
102+
from tinyagent import TinyAgent
103+
from tinyagent.tools.subagent import create_general_subagent, create_coding_subagent
104+
105+
# Create main agent
106+
main_agent = TinyAgent(model="gpt-4o-mini", api_key="your-key")
107+
108+
# Add a general-purpose subagent tool
109+
general_helper = create_general_subagent(
110+
name="helper",
111+
model="gpt-4.1-mini",
112+
max_turns=15
113+
)
114+
main_agent.add_tool(general_helper)
115+
116+
# Add a specialized coding subagent
117+
coding_assistant = create_coding_subagent(
118+
name="coder",
119+
model="claude-3-sonnet",
120+
max_turns=25,
121+
enable_python_tool=True,
122+
enable_shell_tool=True
123+
)
124+
main_agent.add_tool(coding_assistant)
125+
126+
# Use them in conversation
127+
result = await main_agent.run(
128+
"Use coder to implement a sorting algorithm, "
129+
"then use helper to write documentation for it"
130+
)
131+
```
132+
133+
**Advanced Configuration with Parent Inheritance:**
134+
```python
135+
from tinyagent.tools.subagent import SubagentConfig, create_subagent_tool
136+
137+
# Create configuration that inherits from parent
138+
config = SubagentConfig.from_parent_agent(
139+
parent_agent=main_agent, # Inherits API keys, callbacks, logging
140+
model="gpt-4o", # Override model
141+
max_turns=20, # Override max turns
142+
enable_python_tool=True, # Enable code execution
143+
timeout=300 # 5 minute timeout
144+
)
145+
146+
# Create custom subagent with inherited configuration
147+
research_tool = create_subagent_tool("researcher", config)
148+
main_agent.add_tool(research_tool)
149+
```
150+
151+
**Custom Agent Factory Integration:**
152+
```python
153+
def my_custom_agent_factory(**kwargs):
154+
# Create any kind of agent you want
155+
return TinyCodeAgent(
156+
provider="modal",
157+
provider_config={"timeout": 120},
158+
**kwargs
159+
)
160+
161+
# Use custom factory
162+
config = SubagentConfig(model="claude-3-sonnet", max_turns=15)
163+
custom_tool = create_subagent_tool(
164+
name="custom_coder",
165+
config=config,
166+
agent_factory=my_custom_agent_factory
167+
)
168+
main_agent.add_tool(custom_tool)
169+
```
170+
58171
### Upgrading to Anthropic Prompt Caching
59172

60173
If you're upgrading from a previous version and want to add caching:

README.md

Lines changed: 219 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ Inspired by:
3131
## Overview
3232
This is a tiny agent framework that uses MCP and LiteLLM to interact with language models. You have full control over the agent, you can add any tools you like from MCP and extend the agent using its event system.
3333

34-
**Two Main Components:**
34+
**Three Main Components:**
3535
- **TinyAgent**: Core agent with MCP tool integration and extensible hooks
36-
- **TinyCodeAgent**: Specialized agent for secure Python code execution with pluggable providers
36+
- **TinyCodeAgent**: Specialized agent for secure Python code execution with pluggable providers
37+
- **Subagent Tools**: Revolutionary parallel task execution system with context isolation and specialized workers
3738

3839
## Installation
3940

@@ -258,6 +259,206 @@ Each checkpoint includes:
258259

259260
For detailed documentation, see the [TinyCodeAgent README](tinyagent/code_agent/README.md).
260261

262+
## 🚀 Subagent Tools - Parallel Task Execution (New!)
263+
264+
The subagent system enables you to create specialized AI workers that can execute tasks in parallel with complete context isolation. Each subagent operates independently with its own conversation history, resource management, and cleanup.
265+
266+
### Quick Start with Subagents
267+
268+
```python
269+
import asyncio
270+
from tinyagent import TinyAgent
271+
from tinyagent.tools.subagent import create_general_subagent, create_coding_subagent
272+
273+
async def main():
274+
# Create main agent
275+
main_agent = TinyAgent(
276+
model="gpt-4o-mini",
277+
api_key="your-api-key"
278+
)
279+
280+
# Add a general-purpose subagent
281+
helper = create_general_subagent(
282+
name="helper",
283+
model="gpt-4.1-mini",
284+
max_turns=15,
285+
enable_python=True,
286+
enable_shell=True
287+
)
288+
main_agent.add_tool(helper)
289+
290+
# Add a specialized coding subagent
291+
coder = create_coding_subagent(
292+
name="coder",
293+
model="claude-3-sonnet",
294+
max_turns=25
295+
)
296+
main_agent.add_tool(coder)
297+
298+
# Use subagents in parallel
299+
result = await main_agent.run("""
300+
I need help with a Python project:
301+
1. Use coder to implement a binary search algorithm
302+
2. Use helper to create unit tests for it
303+
3. Use helper to benchmark the performance
304+
305+
Make sure both tasks run efficiently and provide comprehensive results.
306+
""")
307+
308+
print(result)
309+
310+
asyncio.run(main())
311+
```
312+
313+
### Specialized Subagent Types
314+
315+
The subagent system provides pre-configured factories for common use cases:
316+
317+
```python
318+
from tinyagent.tools.subagent import (
319+
create_research_subagent,
320+
create_coding_subagent,
321+
create_analysis_subagent,
322+
create_writing_subagent,
323+
create_planning_subagent
324+
)
325+
326+
# Research subagent - optimized for information gathering
327+
researcher = create_research_subagent(
328+
name="researcher",
329+
model="gpt-4o",
330+
max_turns=20
331+
)
332+
333+
# Coding subagent - with Python/shell execution
334+
coder = create_coding_subagent(
335+
name="coder",
336+
model="claude-3-sonnet",
337+
local_execution=True,
338+
timeout=300 # 5 minute timeout
339+
)
340+
341+
# Analysis subagent - for data analysis tasks
342+
analyst = create_analysis_subagent(
343+
name="analyst",
344+
model="gpt-4.1-mini",
345+
enable_python_tool=True
346+
)
347+
348+
# Writing subagent - for content creation
349+
writer = create_writing_subagent(
350+
name="writer",
351+
model="claude-3-haiku",
352+
temperature=0.3
353+
)
354+
355+
# Planning subagent - for strategy and planning
356+
planner = create_planning_subagent(
357+
name="planner",
358+
model="gpt-4o",
359+
max_turns=15
360+
)
361+
362+
# Add all subagents to your main agent
363+
for subagent in [researcher, coder, analyst, writer, planner]:
364+
main_agent.add_tool(subagent)
365+
```
366+
367+
### Advanced Configuration with Parent Inheritance
368+
369+
Subagents can automatically inherit configuration from their parent agent:
370+
371+
```python
372+
from tinyagent.tools.subagent import SubagentConfig, create_subagent_tool
373+
374+
# Create main agent with callbacks and configuration
375+
main_agent = TinyAgent(
376+
model="gpt-4o-mini",
377+
api_key="your-key",
378+
log_manager=my_log_manager,
379+
session_id="main-session"
380+
)
381+
382+
# Create configuration that inherits from parent
383+
config = SubagentConfig.from_parent_agent(
384+
parent_agent=main_agent, # Inherits API keys, logging, session info
385+
model="claude-3-sonnet", # Override specific parameters
386+
max_turns=20,
387+
enable_python_tool=True,
388+
timeout=300, # 5 minute timeout
389+
working_directory="/tmp/subagent"
390+
)
391+
392+
# Create custom subagent with inherited configuration
393+
specialized_tool = create_subagent_tool(
394+
name="specialist",
395+
config=config,
396+
description="A specialized agent for complex analysis tasks"
397+
)
398+
main_agent.add_tool(specialized_tool)
399+
```
400+
401+
### Custom Agent Factories
402+
403+
For maximum flexibility, use custom agent factories to create any type of agent:
404+
405+
```python
406+
from tinyagent.tools.subagent import SubagentConfig, create_subagent_tool
407+
from tinyagent import TinyCodeAgent
408+
409+
def my_custom_factory(**kwargs):
410+
"""Custom factory for creating specialized agents."""
411+
return TinyCodeAgent(
412+
provider="modal", # Use Modal.com for execution
413+
provider_config={
414+
"image": "python:3.11-slim",
415+
"timeout": 180,
416+
"cpu_count": 2
417+
},
418+
tools=[custom_tool_1, custom_tool_2], # Add custom tools
419+
**kwargs
420+
)
421+
422+
# Create subagent with custom factory
423+
config = SubagentConfig(
424+
model="gpt-4.1-mini",
425+
max_turns=15,
426+
timeout=600
427+
)
428+
429+
custom_subagent = create_subagent_tool(
430+
name="custom_executor",
431+
config=config,
432+
agent_factory=my_custom_factory,
433+
description="Custom subagent with Modal.com execution"
434+
)
435+
436+
main_agent.add_tool(custom_subagent)
437+
```
438+
439+
### Key Benefits of Subagents
440+
441+
- **🔄 Parallel Processing**: Execute multiple tasks concurrently with complete isolation
442+
- **🧠 Specialized Intelligence**: Domain-specific agents optimized for particular tasks
443+
- **🛡️ Resource Safety**: Automatic cleanup prevents memory leaks and resource exhaustion
444+
- **🔗 Seamless Integration**: Inherits parent configuration (API keys, callbacks, logging)
445+
- **🎯 Context Isolation**: Independent conversation history per subagent
446+
- **⚙️ Extensible**: Custom agent factories for any agent implementation
447+
- **📊 Execution Tracking**: Complete metadata and execution logs
448+
- **🏗️ Production Ready**: Timeout management, error handling, automatic cleanup
449+
450+
### Subagent vs Regular Tools
451+
452+
| Feature | Regular Tools | Subagents |
453+
|---------|---------------|-----------|
454+
| **Context** | Share parent's context | Independent context |
455+
| **Conversation** | Single shared history | Per-subagent history |
456+
| **Resource Management** | Manual cleanup | Automatic cleanup |
457+
| **Parallel Execution** | Limited | Full support |
458+
| **Specialization** | Generic | Domain-optimized |
459+
| **Timeout Handling** | Basic | Advanced with cleanup |
460+
| **Configuration** | Static | Dynamic with inheritance |
461+
261462
## How the TinyAgent Hook System Works
262463

263464
TinyAgent is designed to be **extensible** via a simple, event-driven hook (callback) system. This allows you to add custom logic, logging, UI, memory, or any other behavior at key points in the agent's lifecycle.
@@ -437,8 +638,9 @@ response = await agent.run("Long prompt here...")
437638

438639
---
439640

440-
## List of Available Hooks
641+
## List of Available Hooks & Tools
441642

643+
### Core Hooks
442644
You can import and use these hooks from `tinyagent.hooks`:
443645

444646
| Hook Name | Description | Example Import |
@@ -451,6 +653,20 @@ You can import and use these hooks from `tinyagent.hooks`:
451653
| `GradioCallback` | Interactive browser-based chat UI: file uploads, live thinking, tool calls, token stats | `from tinyagent.hooks.gradio_callback import GradioCallback` |
452654
| `JupyterNotebookCallback` | Interactive Jupyter notebook integration | `from tinyagent.hooks.jupyter_notebook_callback import JupyterNotebookCallback` |
453655

656+
### Subagent Tools 🚀
657+
Revolutionary parallel task execution system from `tinyagent.tools.subagent`:
658+
659+
| Tool Function | Description | Example Import |
660+
|--------------------------|--------------------------------------------------|-------------------------------------------------|
661+
| `create_general_subagent` | General-purpose subagent with Python/shell execution | `from tinyagent.tools.subagent import create_general_subagent` |
662+
| `create_research_subagent` | Research-optimized subagent for information gathering | `from tinyagent.tools.subagent import create_research_subagent` |
663+
| `create_coding_subagent` | Coding-specialized subagent with execution capabilities | `from tinyagent.tools.subagent import create_coding_subagent` |
664+
| `create_analysis_subagent` | Data analysis subagent with Python tools | `from tinyagent.tools.subagent import create_analysis_subagent` |
665+
| `create_writing_subagent` | Content creation and writing subagent | `from tinyagent.tools.subagent import create_writing_subagent` |
666+
| `create_planning_subagent` | Strategic planning and project management subagent | `from tinyagent.tools.subagent import create_planning_subagent` |
667+
| `create_subagent_tool` | Advanced subagent creation with custom configuration | `from tinyagent.tools.subagent import create_subagent_tool` |
668+
| `SubagentConfig` | Configuration class with parent inheritance | `from tinyagent.tools.subagent import SubagentConfig` |
669+
454670
To see more details and usage, check the docstrings and `run_example()` in each hook file.
455671

456672
## Using the GradioCallback Hook

0 commit comments

Comments
 (0)