Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .prompt
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ from botocore.config import Config

# Configure Bedrock model with maximum capabilities
model = BedrockModel(
model_id="us.anthropic.claude-3-7-sonnet-20250219-v1:0",
model_id="us.anthropic.claude-sonnet-4-20250514-v1:0",
max_tokens=int(os.getenv("STRANDS_MAX_TOKENS", "64000")), # Maximized token output
boto_client_config=Config(
read_timeout=900, # 15 min timeout for long operations
Expand Down Expand Up @@ -378,9 +378,9 @@ export STRANDS_SYSTEM_PROMPT="Your custom prompt here"
- Create agents that can collaborate through shared interfaces

6. **Maximizing Bedrock Performance**
- Use Claude 3.7 Sonnet for best reasoning capabilities
- Use the latest Claude Sonnet model available for best reasoning capabilities
- Configure extended timeouts for complex reasoning tasks
- Enable thinking capability with appropriate token budget
- Use maximal output tokens to handle complex tool responses

I'm here to help you build self-extending agents that continuously evolve their capabilities through autonomous tool creation. Let's build something extraordinary together!
I'm here to help you build self-extending agents that continuously evolve their capabilities through autonomous tool creation. Let's build something extraordinary together!
136 changes: 85 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
# Strands Agent Builder
<div align="center">
<div>
<a href="https://strandsagents.com">
<img src="https://strandsagents.com/latest/assets/logo-auto.svg" alt="Strands Agents" width="55px" height="105px">
</a>
</div>

<h1>
Strands Agent Builder
</h1>

<h2>
A model-driven approach to building AI agents in just a few lines of code.
</h2>

<div align="center">
<a href="https://github.com/strands-agents/agent-builder/graphs/commit-activity"><img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/strands-agents/agent-builder"/></a>
<a href="https://github.com/strands-agents/agent-builder/issues"><img alt="GitHub open issues" src="https://img.shields.io/github/issues/strands-agents/agent-builder"/></a>
<a href="https://github.com/strands-agents/agent-builder/pulls"><img alt="GitHub open pull requests" src="https://img.shields.io/github/issues-pr/strands-agents/agent-builder"/></a>
<a href="https://github.com/strands-agents/agent-builder/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/strands-agents/agent-builder"/></a>
<a href="https://pypi.org/project/strands-agents-builder/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/strands-agents-builder"/></a>
<a href="https://python.org"><img alt="Python versions" src="https://img.shields.io/pypi/pyversions/strands-agents-builder"/></a>
</div>

<p>
<a href="https://strandsagents.com/">Documentation</a>
◆ <a href="https://github.com/strands-agents/samples">Samples</a>
◆ <a href="https://github.com/strands-agents/sdk-python">Python SDK</a>
◆ <a href="https://github.com/strands-agents/tools">Tools</a>
◆ <a href="https://github.com/strands-agents/agent-builder">Agent Builder</a>
◆ <a href="https://github.com/strands-agents/mcp-server">MCP Server</a>
</p>
</div>

An interactive Strands agent toolkit designed to help you build, test, and extend your own custom AI agents and tools. With the Strands Agent Builder, you can create specialized agents, develop custom tools, and compose complex AI workflows—all from your terminal.

Expand Down Expand Up @@ -38,18 +70,33 @@ strands --kb YOUR_KB_ID "Load my previous calculator tool and enhance it with sc

Strands comes with a comprehensive set of built-in tools:

- **shell**: Run command-line operations with interactive support
- **editor**: View and edit files with syntax highlighting
- **http_request**: Make API calls with authentication support
- **python_repl**: Execute Python code interactively
- **calculator**: Perform mathematical operations powered by SymPy
- **retrieve**: Query knowledge bases for relevant information
- **store_in_kb**: Save content to knowledge bases for future reference
- **load_tool**: Dynamically load additional tools at runtime
- **agent_graph**: Create and manage graphs of agents
- **calculator**: Perform mathematical operations
- **cron**: Task scheduling with cron jobs
- **current_time**: Get the current date and time
- **editor**: File editing operations like line edits, search, and undo
- **environment**: Manage environment variables
- **strands**: Create nested agent instances with specialized capabilities
- **dialog**: Create interactive dialog interfaces
- **use_aws**: Make AWS API calls through boto3
- **generate_image**: Create AI generated images with Amazon Bedrock
- **http_request**: Make API calls, fetch web data, and call local HTTP servers
- **image_reader**: Process and analyze images
- **journal**: Create structured tasks and logs for agents to manage and work from
- **load_tool**: Dynamically load more tools at runtime
- **memory**: Agent memory persistence in Amazon Bedrock Knowledge Bases
- **nova_reels**: Create AI generated videos with Nova Reels on Amazon Bedrock
- **python_repl**: Run Python code
- **retrieve**: Semantically retrieve data from Amazon Bedrock Knowledge Bases for RAG, memory, and other purposes
- **shell**: Execute shell commands
- **slack**: Slack integration with real-time events, API access, and message sending
- **speak**: Generate speech from text using macOS say command or Amazon Polly
- **stop**: Force stop the agent event loop
- **store_in_kb**: Save content to knowledge bases for future reference
- **strand**: Create nested agent instances with specialized capabilities
- **swarm**: Coordinate multiple AI agents in a swarm / network of agents
- **think**: Perform deep thinking by creating parallel branches of agentic reasoning
- **use_aws**: Interact with AWS services
- **use_llm**: Run a new AI event loop with custom prompts
- **welcome**: Manage the Strands Agent Builder welcome text
- **workflow**: Orchestrate sequenced workflows

## Knowledge Base Integration

Expand All @@ -70,26 +117,6 @@ Features:
- 🛠️ Ability to iteratively improve tools across sessions
- 🔍 Find and extend tools built in previous sessions

## Nested Agent Capabilities

Use the `strands` tool to prototype and test specialized sub-agents with their own tools and system prompts:

```python
# Create a specialized data analysis agent
agent.tool.strand(
query="Build and test a data analysis agent",
tool_names=["python_repl", "editor", "http_request"],
system_prompt="You're an AI specialized in data analysis. Your task is to build tools for data processing and visualization."
)

# Create a tool-building agent focused on web automation
agent.tool.strand(
query="Create a set of web automation tools for browser testing",
tool_names=["editor", "python_repl", "shell"],
system_prompt="You're an expert in creating web automation tools. Your specialty is developing reliable browser testing utilities."
)
```

## Model Configuration

### Optimized Defaults
Expand All @@ -98,8 +125,8 @@ Strands comes with optimized, maxed-out configuration settings for the Bedrock m

```json
{
"model_id": "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"max_tokens": 64000,
"model_id": "us.anthropic.claude-sonnet-4-20250514-v1:0",
"max_tokens": 32767,
"boto_client_config": {
"read_timeout": 900,
"connect_timeout": 900,
Expand All @@ -118,8 +145,8 @@ Strands comes with optimized, maxed-out configuration settings for the Bedrock m
```

These settings provide:
- Claude 3.7 Sonnet (latest high-performance model)
- Maximum token output (64,000 tokens)
- Claude Sonnet 4 (latest high-performance model)
- Maximum token output (32,768 tokens)
- Extended timeouts (15 minutes) for complex operations
- Automatic retries with adaptive backoff
- Enabled thinking capability with 2,048 token budget for recursive reasoning
Expand Down Expand Up @@ -176,22 +203,29 @@ export STRANDS_SYSTEM_PROMPT="You are a Python expert."
echo "You are a security expert." > .prompt
```

## Contributing
## Exit

```bash
git clone https://github.com/strands-agents/agent-builder.git ~/.agent-builder
cd ~/.agent-builder
python3 -m venv venv && source venv/bin/activate
pip3 install -e .
pip3 install -e ".[test]"

# Run tests
hatch run test # Run all tests with verbose coverage output
hatch run test -k test_pattern # Run specific tests matching a pattern
```
Type `exit`, `quit`, or press `Ctrl+C`/`Ctrl+D`

Testing is managed through hatch scripting in pyproject.toml.
## Contributing ❤️

## Exit
We welcome contributions! See our [Contributing Guide](CONTRIBUTING.md) for details on:
- Reporting bugs & features
- Development setup
- Contributing via Pull Requests
- Code of Conduct
- Reporting of security issues

Type `exit`, `quit`, or press `Ctrl+C`/`Ctrl+D`
## License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.

## Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.

## ⚠️ Preview Status

Strands Agents is currently in public preview. During this period:
- APIs may change as we refine the SDK
- We welcome feedback and contributions
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "strands-agents-builder"
version = "0.1.1"
version = "0.1.2"
description = "An example Strands agent demonstrating streaming, tool use, and interactivity from your terminal. This agent builder can help you to build your own agents and tools."
readme = "README.md"
requires-python = ">=3.10"
Expand Down
4 changes: 4 additions & 0 deletions src/strands_agents_builder/models/bedrock.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Create instance of SDK's Bedrock model provider."""

from botocore.config import Config as BotocoreConfig
from strands.models import BedrockModel
from strands.types.models import Model
from typing_extensions import Unpack
Expand All @@ -14,5 +15,8 @@ def instance(**model_config: Unpack[BedrockModel.BedrockConfig]) -> Model:
Returns:
Bedrock model provider.
"""
# Handle conversion of boto_client_config from dict to BotocoreConfig
if "boto_client_config" in model_config and isinstance(model_config["boto_client_config"], dict):
model_config["boto_client_config"] = BotocoreConfig(**model_config["boto_client_config"])

return BedrockModel(**model_config)
44 changes: 30 additions & 14 deletions src/strands_agents_builder/strands.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,25 @@
from strands_tools import (
agent_graph,
calculator,
cron,
current_time,
editor,
environment,
file_read,
file_write,
generate_image,
http_request,
image_reader,
journal,
load_tool,
memory,
nova_reels,
python_repl,
retrieve,
shell,
slack,
speak,
stop,
swarm,
think,
use_aws,
Expand All @@ -37,7 +45,7 @@
from strands_agents_builder.utils.kb_utils import load_system_prompt, store_conversation_in_kb
from strands_agents_builder.utils.welcome_utils import render_goodbye_message, render_welcome_message

# Custom tools, handlers, utils
# Custom tools
from tools import (
store_in_kb,
strand,
Expand Down Expand Up @@ -80,24 +88,31 @@ def main():
system_prompt = load_system_prompt()

tools = [
shell,
agent_graph,
calculator,
cron,
current_time,
editor,
environment,
file_read,
file_write,
generate_image,
http_request,
image_reader,
journal,
load_tool,
memory,
nova_reels,
python_repl,
calculator,
retrieve,
shell,
slack,
speak,
stop,
swarm,
think,
use_aws,
load_tool,
environment,
use_llm,
think,
load_tool,
journal,
image_reader,
generate_image,
nova_reels,
agent_graph,
swarm,
workflow,
# Strands tools
store_in_kb,
Expand Down Expand Up @@ -133,7 +148,7 @@ def main():
render_welcome_message(welcome_text)
while True:
try:
user_input = get_user_input("\n~ ")
user_input = get_user_input("\n~ ", default="", keyboard_interrupt_return_default=False)
if user_input.lower() in ["exit", "quit"]:
render_goodbye_message()
break
Expand Down Expand Up @@ -177,6 +192,7 @@ def main():
render_goodbye_message()
break
except Exception as e:
callback_handler(force_stop=True) # Stop spinners
print(f"\nError: {str(e)}")


Expand Down
4 changes: 2 additions & 2 deletions src/strands_agents_builder/utils/model_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

# Default model configuration
DEFAULT_MODEL_CONFIG = {
"model_id": "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"max_tokens": int(os.getenv("STRANDS_MAX_TOKENS", "64000")),
"model_id": "us.anthropic.claude-sonnet-4-20250514-v1:0",
"max_tokens": int(os.getenv("STRANDS_MAX_TOKENS", "32768")),
"boto_client_config": Config(
read_timeout=900,
connect_timeout=900,
Expand Down
11 changes: 9 additions & 2 deletions tests/test_strands.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ def test_interactive_mode(
# Verify welcome message was rendered
mock_welcome_message.assert_called_once()

# Verify user input was called with the correct parameters
mock_user_input.assert_called_with("\n~ ", default="", keyboard_interrupt_return_default=False)

# Verify user input was processed
mock_agent.assert_called_with("test query", system_prompt=mock.ANY)

Expand Down Expand Up @@ -107,7 +110,7 @@ def test_empty_input(
):
"""Test handling of empty input"""
# Setup mocks - empty input followed by exit
mock_user_input.side_effect = ["", "exit"]
mock_user_input.side_effect = ["", " ", "\t", "exit"]

# Mock sys.argv
monkeypatch.setattr(sys, "argv", ["strands"])
Expand Down Expand Up @@ -167,7 +170,8 @@ def test_eof_error_exception(self, mock_goodbye, mock_agent, mock_input):
@mock.patch.object(strands, "get_user_input")
@mock.patch.object(strands, "Agent")
@mock.patch.object(strands, "print")
def test_general_exception_handling(self, mock_print, mock_agent, mock_input):
@mock.patch.object(strands, "callback_handler")
def test_general_exception_handling(self, mock_callback_handler, mock_print, mock_agent, mock_input):
"""Test handling of general exceptions in interactive mode"""
# Setup mocks
mock_agent_instance = mock.MagicMock()
Expand All @@ -187,6 +191,9 @@ def test_general_exception_handling(self, mock_print, mock_agent, mock_input):
# Verify error was printed
mock_print.assert_any_call("\nError: Test error")

# Verify callback_handler was called to stop spinners
mock_callback_handler.assert_called_once_with(force_stop=True)


class TestCommandLine:
"""Test cases for command line mode functionality"""
Expand Down