diff --git a/python/01-learn/01-first-agent/01-first-agent.ipynb b/python/01-learn/01-first-agent/01-first-agent.ipynb index 2f0b3559b..61912d4fc 100644 --- a/python/01-learn/01-first-agent/01-first-agent.ipynb +++ b/python/01-learn/01-first-agent/01-first-agent.ipynb @@ -17,8 +17,8 @@ "| Agent structure | Single agent |\n", "| Model provider | Amazon Bedrock |\n", "| Model | Anthropic Claude Sonnet 4.5 |\n", - "| Native tools used | calculator |\n", - "| Custom tools created | weather, websearch |\n", + "| Native tools used | none |\n", + "| Custom tools created | calculator, weather, websearch |\n", "| Strands features | Agent, @tool decorator, BedrockModel |" ] }, @@ -59,7 +59,7 @@ "source": [ "# Install Strands using pip\n", "\n", - "!pip install strands-agents strands-agents-tools" + "!pip install strands-agents" ] }, { @@ -113,7 +113,7 @@ "source": [ "### Add tools to the agent\n", "\n", - "The [strands-agents-tools](https://github.com/strands-agents/tools) repository provides some built-in tools that you can import. You can also create custom tools using the `@tool` decorator. The function's typed arguments and docstring are not just documentation. Strands turns them into the tool's input schema, which is what the model reads to decide when and how to call the tool. We can create agents with built-in and custom tools. For instance, adding the built-in tool of a calculator and a custom tool for getting the weather, you get the following architecture:\n", + "You create custom tools using the `@tool` decorator. The [strands-agents-tools](https://github.com/strands-agents/tools) repository also provides pre-built tools that you can import. The function's typed arguments and docstring are not just documentation. Strands turns them into the tool's input schema, which is what the model reads to decide when and how to call the tool. We can create agents with built-in and custom tools. For instance, defining a small calculator tool and a custom tool for getting the weather, you get the following architecture:\n", "
\n", " \n", "
\n", @@ -128,8 +128,29 @@ "metadata": {}, "outputs": [], "source": [ + "import operator\n", + "\n", "from strands import Agent, tool\n", - "from strands_tools import calculator # Import the calculator tool\n", + "\n", + "_OPS = {\n", + " \"+\": operator.add,\n", + " \"-\": operator.sub,\n", + " \"*\": operator.mul,\n", + " \"/\": operator.truediv,\n", + " \"**\": operator.pow,\n", + "}\n", + "\n", + "\n", + "@tool\n", + "def calculator(a: float, b: float, op: str) -> float:\n", + " \"\"\"Apply an arithmetic operator to two numbers.\n", + "\n", + " Args:\n", + " a: Left operand.\n", + " b: Right operand.\n", + " op: One of \"+\", \"-\", \"*\", \"/\", \"**\".\n", + " \"\"\"\n", + " return _OPS[op](a, b)\n", "\n", "# Create a custom tool\n", "@tool\n", @@ -169,7 +190,7 @@ "outputs": [], "source": [ "# Alternatively, you can invoke the tool directly like so:\n", - "agent.tool.calculator(expression=\"sin(x)\", mode=\"derive\", wrt=\"x\", order=2)" + "agent.tool.calculator(a=144, b=0.5, op=\"**\")" ] }, { diff --git a/python/01-learn/01-first-agent/README.md b/python/01-learn/01-first-agent/README.md index 01f013ee6..47b8345a1 100644 --- a/python/01-learn/01-first-agent/README.md +++ b/python/01-learn/01-first-agent/README.md @@ -10,7 +10,7 @@ This tutorial walks you through building your first Strands agent. You start wit |------------------------|----------------------------------------------------------| | **Strands Features** | `Agent`, `@tool` decorator, `BedrockModel` | | **Agent Pattern** | Single agent | -| **Tools** | Built-in (`calculator`) and custom (`@tool`) | +| **Tools** | Custom tools via the `@tool` decorator | | **Model** | Claude Sonnet 4.5 on Amazon Bedrock (`us.anthropic.claude-sonnet-4-5-20250929-v1:0`) | ## Key Concepts @@ -41,7 +41,7 @@ The command-line script runs the RecipeBot interactively: 1. **Install dependencies:** ```bash - pip install strands-agents strands-agents-tools + pip install strands-agents ``` 2. **Run the notebook:** open [`01-first-agent.ipynb`](./01-first-agent.ipynb) and run the cells in order. It covers: diff --git a/python/01-learn/02-tools-and-mcp/02-custom-tools/custom-tools-with-strands-agents.ipynb b/python/01-learn/02-tools-and-mcp/02-custom-tools/custom-tools-with-strands-agents.ipynb index 8921fd595..76a5a9d60 100644 --- a/python/01-learn/02-tools-and-mcp/02-custom-tools/custom-tools-with-strands-agents.ipynb +++ b/python/01-learn/02-tools-and-mcp/02-custom-tools/custom-tools-with-strands-agents.ipynb @@ -21,8 +21,8 @@ "| Agent structure | Single agent |\n", "| Model provider | Amazon Bedrock |\n", "| Model | Anthropic Claude Sonnet 4.5 |\n", - "| Native tools used | current_time, calculator |\n", - "| Custom tools created | create_appointment, list_appointments, update_appointment |\n", + "| Native tools used | none |\n", + "| Custom tools created | calculator, current_time, create_appointment, list_appointments, update_appointment |\n", "| Strands features | @tool decorator, TOOL_SPEC, BedrockModel extended thinking |\n" ] }, @@ -541,7 +541,7 @@ "outputs": [], "source": [ "system_prompt = \"\"\"You are a helpful personal assistant that specializes in managing my appointments and calendar. \n", - "You have access to appointment management tools, a calculator, and can check the current time to help me organize my schedule effectively. \n", + "You have access to appointment management tools, a calculator, and a clock to help me organize my schedule effectively. \n", "Always provide the appointment id so that I can update it if required\"\"\"" ] }, @@ -592,9 +592,9 @@ } }, "source": [ - "#### Import built-in tools\n", + "#### Define the tools our agent needs\n", "\n", - "The next step to build our agent is to import our Strands Agents built-in tools. Strands Agents provides a set of commonly used built-in tools in the optional package `strands-agents-tools`, which you import as `strands_tools`. You have tools for RAG, memory, file operations, code interpretation and others available in this repo. For our example we will use the `current_time` tool to provide our agent with the information about the current time and the `calculator` tool to do some math" + "The next step is to define the remaining tools our agent needs. Strands Agents also offers an optional package of pre-built tools, `strands-agents-tools`, with tools for RAG, memory, file operations, code interpretation and more. For this example we keep everything self-contained and define two small tools of our own: a `calculator` to do some math and a `current_time` tool so the agent can resolve relative dates like \"tomorrow\"." ] }, { @@ -608,7 +608,36 @@ }, "outputs": [], "source": [ - "from strands_tools import calculator, current_time" + "import operator\n", + "from datetime import datetime, timezone\n", + "\n", + "from strands import tool\n", + "\n", + "_OPS = {\n", + " \"+\": operator.add,\n", + " \"-\": operator.sub,\n", + " \"*\": operator.mul,\n", + " \"/\": operator.truediv,\n", + " \"**\": operator.pow,\n", + "}\n", + "\n", + "\n", + "@tool\n", + "def calculator(a: float, b: float, op: str) -> float:\n", + " \"\"\"Apply an arithmetic operator to two numbers.\n", + "\n", + " Args:\n", + " a: Left operand.\n", + " b: Right operand.\n", + " op: One of \"+\", \"-\", \"*\", \"/\", \"**\".\n", + " \"\"\"\n", + " return _OPS[op](a, b)\n", + "\n", + "\n", + "@tool\n", + "def current_time() -> str:\n", + " \"\"\"Get the current UTC date and time in ISO 8601 format.\"\"\"\n", + " return datetime.now(timezone.utc).isoformat()" ] }, { @@ -640,8 +669,8 @@ " model=model,\n", " system_prompt=system_prompt,\n", " tools=[\n", - " current_time,\n", " calculator,\n", + " current_time,\n", " create_appointment,\n", " list_appointments,\n", " update_appointment,\n", @@ -949,18 +978,18 @@ }, "outputs": [], "source": [ - "current_time_result = agent.tool.current_time()\n", - "print(\"Current Time direct tool call result:\")\n", - "print(current_time_result)\n", - "current_time_direct_tool_messages = agent.messages[-4:]\n", - "print(\"Current Time direct tool call messages:\")\n", - "print(current_time_direct_tool_messages)\n", + "calculator_result = agent.tool.calculator(a=2, b=2, op=\"+\")\n", + "print(\"Calculator direct tool call result:\")\n", + "print(calculator_result)\n", + "calculator_direct_tool_messages = agent.messages[-4:]\n", + "print(\"Calculator direct tool call messages:\")\n", + "print(calculator_direct_tool_messages)\n", "\n", "agent.record_direct_tool_call = False # Set the record_direct_tool_call to False\n", "agent.tool.list_appointments()\n", "after_disable_record_messages = agent.messages[-4:]\n", "print(\"After disabling record direct tool call messages, history should not have changed:\")\n", - "print(current_time_direct_tool_messages == after_disable_record_messages)" + "print(calculator_direct_tool_messages == after_disable_record_messages)" ] }, { @@ -1061,7 +1090,7 @@ "outputs": [], "source": [ "thinking_system_prompt = \"\"\"You are a helpful personal assistant that specializes in managing my appointments and calendar. \n", - "You have access to appointment management tools, a calculator, and can check the current time to help me organize my schedule effectively. \n", + "You have access to appointment management tools, a calculator, and a clock to help me organize my schedule effectively. \n", "You think through your problem, step by step, to come up with an answer.\n", "Always provide the appointment id so that I can update it if required\"\"\"\n", "\n", @@ -1069,8 +1098,8 @@ " model=thinking_model,\n", " system_prompt=thinking_system_prompt,\n", " tools=[\n", - " current_time,\n", " calculator,\n", + " current_time,\n", " create_appointment,\n", " list_appointments,\n", " update_appointment,\n", diff --git a/python/01-learn/02-tools-and-mcp/02-custom-tools/requirements.txt b/python/01-learn/02-tools-and-mcp/02-custom-tools/requirements.txt index 3cbdb2a30..73a545e0d 100644 --- a/python/01-learn/02-tools-and-mcp/02-custom-tools/requirements.txt +++ b/python/01-learn/02-tools-and-mcp/02-custom-tools/requirements.txt @@ -1,2 +1 @@ -strands-agents -strands-agents-tools \ No newline at end of file +strands-agents \ No newline at end of file diff --git a/python/01-learn/04-streaming/requirements.txt b/python/01-learn/04-streaming/requirements.txt index 2596ecf06..b08a1014a 100644 --- a/python/01-learn/04-streaming/requirements.txt +++ b/python/01-learn/04-streaming/requirements.txt @@ -1,7 +1,6 @@ fastapi uv strands-agents -strands-agents-tools uvicorn pydantic httpx \ No newline at end of file diff --git a/python/01-learn/04-streaming/streaming.ipynb b/python/01-learn/04-streaming/streaming.ipynb index d922ba45f..de835cd93 100644 --- a/python/01-learn/04-streaming/streaming.ipynb +++ b/python/01-learn/04-streaming/streaming.ipynb @@ -32,8 +32,8 @@ "|--------------------|---------------------------------------------------|\n", "|Feature used |async iterators, callback handlers |\n", "|Agent Structure |single agent architecture |\n", - "|Native tools used |calculator |\n", - "|Custom tools created|Weather forecast |\n", + "|Native tools used |none |\n", + "|Custom tools created|calculator, Weather forecast |\n", "\n", "" ] @@ -87,7 +87,39 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": "import asyncio\n\nimport httpx\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom pydantic import BaseModel\nfrom strands import Agent, tool\nfrom strands_tools import calculator" + "source": [ + "import operator\n", + "\n", + "import asyncio\n", + "\n", + "import httpx\n", + "import uvicorn\n", + "from fastapi import FastAPI\n", + "from fastapi.responses import StreamingResponse\n", + "from pydantic import BaseModel\n", + "from strands import Agent, tool\n", + "\n", + "_OPS = {\n", + " \"+\": operator.add,\n", + " \"-\": operator.sub,\n", + " \"*\": operator.mul,\n", + " \"/\": operator.truediv,\n", + " \"**\": operator.pow,\n", + "}\n", + "\n", + "\n", + "@tool\n", + "def calculator(a: float, b: float, op: str) -> float:\n", + " \"\"\"Apply an arithmetic operator to two numbers.\n", + "\n", + " Args:\n", + " a: Left operand.\n", + " b: Right operand.\n", + " op: One of \"+\", \"-\", \"*\", \"/\", \"**\".\n", + " \"\"\"\n", + " return _OPS[op](a, b)\n", + "\n" + ] }, { "cell_type": "markdown", @@ -107,7 +139,7 @@ "source": [ "### Creating and invoking agent with stream_async\n", "\n", - "Let's now create our agent with a built-in calculator tool and no `callback_handler`. We will use the `stream_async` method to iterate over the streamed agent events" + "Let's now create our agent with the calculator tool defined above and no `callback_handler`. We will use the `stream_async` method to iterate over the streamed agent events" ] }, { @@ -378,4 +410,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/python/01-learn/09-bidi-streaming/README.md b/python/01-learn/09-bidi-streaming/README.md index 778cb1d4b..73ceca4c6 100644 --- a/python/01-learn/09-bidi-streaming/README.md +++ b/python/01-learn/09-bidi-streaming/README.md @@ -12,9 +12,31 @@ A bidirectional streaming agent enables real-time, two-way voice conversations w These samples demonstrates how to build voice-enabled AI agents using Strands with models like AWS Nova Sonic, Google Gemini Live, and OpenAI Realtime API. ```python +import operator + from strands.experimental.bidi.agent import BidiAgent +from strands import tool from strands.experimental.bidi.models.nova_sonic import BidiNovaSonicModel -from strands_tools import calculator + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) # Create a voice-enabled agent with tools agent = BidiAgent( @@ -78,7 +100,7 @@ pip install -r requirements.txt Or install directly: ```bash -pip install fastapi uvicorn strands-agents[bidi-all] strands-agents-tools +pip install fastapi uvicorn strands-agents[bidi-all] ``` 3. **Set up credentials** (for the models you want to use) @@ -224,8 +246,7 @@ Sent when the user interrupts the agent. Stop playing current audio and clear bu ```json { "type": "tool_use_stream", - "tool_name": "calculator", - "tool_input": {"operation": "multiply", "a": 25, "b": 8} + "current_tool_use": {"name": "calculator", "input": {"a": 25, "b": 8, "op": "*"}} } ``` Notification that the agent is executing a tool. @@ -234,8 +255,7 @@ Notification that the agent is executing a tool. ```json { "type": "tool_result", - "tool_name": "calculator", - "result": 200 + "tool_result": {"content": [{"text": "200.0"}]} } ``` The result returned from tool execution. @@ -255,7 +275,30 @@ The result returned from tool execution. Tools can be added to the `tools` parameter in `websocket_example.py`. The agent is already configured with the calculator tool: ```python -from strands_tools import calculator +import operator + +from strands import tool + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) + agent = BidiAgent( model=model, @@ -264,7 +307,7 @@ agent = BidiAgent( ) ``` -You can add additional tools from `strands_tools` or create custom tools following the Strands tools specification. +You can add additional tools from `strands.vended_tools` or create custom tools following the Strands tools specification. ## Event Format Reference @@ -375,9 +418,9 @@ Notifies that the agent is executing a tool. "current_tool_use": { "name": "calculator", "input": { - "operation": "multiply", "a": 25, - "b": 8 + "b": 8, + "op": "*" } } } @@ -396,7 +439,7 @@ Returns the result from tool execution. "tool_result": { "content": [ { - "text": "200" + "text": "200.0" } ] } diff --git a/python/01-learn/09-bidi-streaming/requirements.txt b/python/01-learn/09-bidi-streaming/requirements.txt index d21af8e79..6861e9e94 100644 --- a/python/01-learn/09-bidi-streaming/requirements.txt +++ b/python/01-learn/09-bidi-streaming/requirements.txt @@ -74,8 +74,7 @@ smithy-json==0.1.0 sniffio==1.3.1 sse-starlette==3.0.3 starlette==0.49.3 -strands-agents>=1.23.0,<2.0 -strands-agents-tools>=0.2.19,<1.0 +strands-agents>=1.50.0,<2.0 sympy==1.14.0 tenacity==9.1.2 typing-inspection==0.4.2 diff --git a/python/01-learn/09-bidi-streaming/test_simple_gemini.py b/python/01-learn/09-bidi-streaming/test_simple_gemini.py index 3a6f0343c..21dfbbb8d 100644 --- a/python/01-learn/09-bidi-streaming/test_simple_gemini.py +++ b/python/01-learn/09-bidi-streaming/test_simple_gemini.py @@ -9,7 +9,7 @@ from strands.experimental.bidi.io.audio import BidiAudioIO from strands.experimental.bidi.io.text import BidiTextIO from strands.experimental.bidi.models.gemini_live import BidiGeminiLiveModel -from strands_tools import calculator +from strands.vended_tools import sleep async def main(): @@ -23,8 +23,8 @@ async def main(): model = BidiGeminiLiveModel(client_config={"api_key": api_key}) - agent = BidiAgent(model=model, tools=[calculator]) - print("Gemini Live - Try: 'What is 25 times 8?'") + agent = BidiAgent(model=model, tools=[sleep]) + print("Gemini Live - Try: 'Pause for 2 seconds'") await agent.run(inputs=[audio_io.input()], outputs=[audio_io.output(), text_io.output()]) diff --git a/python/01-learn/09-bidi-streaming/test_simple_novasonic.py b/python/01-learn/09-bidi-streaming/test_simple_novasonic.py index f8e3a2dd4..0d8443e12 100644 --- a/python/01-learn/09-bidi-streaming/test_simple_novasonic.py +++ b/python/01-learn/09-bidi-streaming/test_simple_novasonic.py @@ -6,7 +6,7 @@ from strands.experimental.bidi.io.audio import BidiAudioIO from strands.experimental.bidi.io.text import BidiTextIO from strands.experimental.bidi.models.nova_sonic import BidiNovaSonicModel -from strands_tools import calculator +from strands.vended_tools import sleep async def main(): @@ -23,11 +23,11 @@ async def main(): "endpointingSensitivity": "HIGH" # HIGH, MEDIUM, LOW } }, - tools=[calculator], ) - agent = BidiAgent(model=model, tools=[calculator]) - print("Nova Sonic - Try: 'What is 25 times 8?'") + # Tools are registered on the agent, not the model. + agent = BidiAgent(model=model, tools=[sleep]) + print("Nova Sonic - Try: 'Pause for 2 seconds'") await agent.run(inputs=[audio_io.input()], outputs=[audio_io.output(), text_io.output()]) diff --git a/python/01-learn/09-bidi-streaming/test_simple_openai.py b/python/01-learn/09-bidi-streaming/test_simple_openai.py index 4f6318a9c..67ea7cc4f 100644 --- a/python/01-learn/09-bidi-streaming/test_simple_openai.py +++ b/python/01-learn/09-bidi-streaming/test_simple_openai.py @@ -8,7 +8,7 @@ from strands.experimental.bidi.io.audio import BidiAudioIO from strands.experimental.bidi.io.text import BidiTextIO from strands.experimental.bidi.models.openai_realtime import BidiOpenAIRealtimeModel -from strands_tools import calculator +from strands.vended_tools import sleep async def main(): @@ -18,8 +18,8 @@ async def main(): model = BidiOpenAIRealtimeModel() - agent = BidiAgent(model=model, tools=[calculator]) - print("OpenAI Realtime - Try: 'What is 25 times 8?'") + agent = BidiAgent(model=model, tools=[sleep]) + print("OpenAI Realtime - Try: 'Pause for 2 seconds'") await agent.run(inputs=[audio_io.input()], outputs=[audio_io.output(), text_io.output()]) diff --git a/python/01-learn/09-bidi-streaming/websocket_example.py b/python/01-learn/09-bidi-streaming/websocket_example.py index e3d65d0af..9b159a654 100644 --- a/python/01-learn/09-bidi-streaming/websocket_example.py +++ b/python/01-learn/09-bidi-streaming/websocket_example.py @@ -3,6 +3,7 @@ import json import logging +import operator import os import sys import threading @@ -14,6 +15,7 @@ from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect from fastapi.responses import HTMLResponse +from strands import tool from strands.experimental.bidi.agent import BidiAgent from strands.experimental.bidi.models.gemini_live import BidiGeminiLiveModel from strands.experimental.bidi.models.nova_sonic import BidiNovaSonicModel @@ -23,7 +25,27 @@ BidiImageInputEvent, BidiTextInputEvent, ) -from strands_tools import calculator + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) + logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -84,7 +106,6 @@ async def websocket_endpoint(websocket: WebSocket, model_name: str): "voice": "matthew", } }, - tools=[calculator], ) elif model_name == "gemini": model = BidiGeminiLiveModel(client_config={"api_key": os.environ.get("GOOGLE_API_KEY")}) diff --git a/python/01-learn/19-structured-output/README.md b/python/01-learn/19-structured-output/README.md index fd75b078b..e1a5b601c 100644 --- a/python/01-learn/19-structured-output/README.md +++ b/python/01-learn/19-structured-output/README.md @@ -14,7 +14,7 @@ Under the hood, the SDK registers your model as a dynamic tool, the LLM calls it |------------------------|----------------------------------------------------------------------| | **Strands Features** | Structured Output, Pydantic Validation, Tool Integration | | **Agent Pattern** | Single agent with structured output | -| **Tools** | `calculator` (from strands-agents-tools) | +| **Tools** | `calculator` (defined in the notebook) | | **Model** | Claude Sonnet 4.5 on Amazon Bedrock | ## How It Works diff --git a/python/01-learn/19-structured-output/requirements.txt b/python/01-learn/19-structured-output/requirements.txt index 155611e78..20f795726 100644 --- a/python/01-learn/19-structured-output/requirements.txt +++ b/python/01-learn/19-structured-output/requirements.txt @@ -1,3 +1,2 @@ strands-agents -strands-agents-tools pydantic diff --git a/python/01-learn/19-structured-output/structured-output.ipynb b/python/01-learn/19-structured-output/structured-output.ipynb index 782b96d3e..84c13ba54 100644 --- a/python/01-learn/19-structured-output/structured-output.ipynb +++ b/python/01-learn/19-structured-output/structured-output.ipynb @@ -549,7 +549,7 @@ "\n", "In practice, agents don't just format text — they use tools to gather information first, then structure the result. The structured output tool coexists with regular tools. The LLM uses regular tools to do work, then calls the structured output tool last to return the final answer.\n", "\n", - "Let's use the `calculator` tool from `strands-agents-tools` so the agent can perform calculations before returning a structured result." + "Let's define a small `calculator` tool so the agent can perform calculations before returning a structured result." ] }, { @@ -559,7 +559,29 @@ "metadata": {}, "outputs": [], "source": [ - "from strands_tools import calculator\n", + "import operator\n", + "\n", + "from strands import tool\n", + "\n", + "_OPS = {\n", + " \"+\": operator.add,\n", + " \"-\": operator.sub,\n", + " \"*\": operator.mul,\n", + " \"/\": operator.truediv,\n", + " \"**\": operator.pow,\n", + "}\n", + "\n", + "\n", + "@tool\n", + "def calculator(a: float, b: float, op: str) -> float:\n", + " \"\"\"Apply an arithmetic operator to two numbers.\n", + "\n", + " Args:\n", + " a: Left operand.\n", + " b: Right operand.\n", + " op: One of \"+\", \"-\", \"*\", \"/\", \"**\".\n", + " \"\"\"\n", + " return _OPS[op](a, b)\n", "\n", "\n", "class InvestmentAnalysis(BaseModel):\n", diff --git a/python/03-integrate/protocols/a2a-native/server.py b/python/03-integrate/protocols/a2a-native/server.py index b5788eec9..2b93ec14f 100644 --- a/python/03-integrate/protocols/a2a-native/server.py +++ b/python/03-integrate/protocols/a2a-native/server.py @@ -1,6 +1,28 @@ -from strands import Agent +import operator + +from strands import Agent, tool from strands.multiagent.a2a import A2AServer -from strands_tools.calculator import calculator + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) + # Create a Strands agent with calculator tool strands_agent = Agent( diff --git a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/company_analysis_agent.py b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/company_analysis_agent.py index a7caa3f37..7ee3446bc 100644 --- a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/company_analysis_agent.py +++ b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/company_analysis_agent.py @@ -15,7 +15,7 @@ import requests from strands import Agent, tool from strands.models import BedrockModel -from strands_tools import think, http_request +from strands_tools import http_request @tool @@ -433,7 +433,7 @@ def create_company_analysis_agent(): - Overall Assessment """, model=BedrockModel(model_id="us.anthropic.claude-opus-4-6-v1"), - tools=[get_company_info, get_stock_news, http_request, think], + tools=[get_company_info, get_stock_news, http_request], ) diff --git a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/finance_assistant_swarm.py b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/finance_assistant_swarm.py index c597b773b..caa10e303 100644 --- a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/finance_assistant_swarm.py +++ b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/finance_assistant_swarm.py @@ -14,7 +14,6 @@ from strands import Agent, tool from strands.models import BedrockModel from strands.multiagent import Swarm -from strands_tools import think import yfinance as yf from stock_price_agent import get_stock_prices, create_stock_price_agent @@ -143,7 +142,7 @@ def create_orchestration_agent() -> Agent: WORKFLOW: 1. Get real stock data using get_real_stock_data with the ticker symbol 2. Get ONE collaborative analysis using analyze_company_with_collaborative_swarm — pass ONLY the ticker symbol (e.g. "ALK"), NOT a full sentence - 3. Synthesize using think tool for deep strategic insights + 3. Synthesize the findings into deep strategic insights CRITICAL RULES: - When calling analyze_company_with_collaborative_swarm, pass ONLY the stock ticker symbol (e.g. "ALK", "AAPL"), never a full sentence @@ -159,7 +158,7 @@ def create_orchestration_agent() -> Agent: 4. Market Sentiment Analysis (news + trends) 5. Investment Recommendation (buy/hold/sell with rationale)""", model=BedrockModel(model_id=ORCHESTRATOR_MODEL_ID), - tools=[get_real_stock_data, analyze_company_with_collaborative_swarm, think], + tools=[get_real_stock_data, analyze_company_with_collaborative_swarm], ) def create_initial_messages() -> List[Dict]: diff --git a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/financial_metrics_agent.py b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/financial_metrics_agent.py index d2227e686..2807259ab 100644 --- a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/financial_metrics_agent.py +++ b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/financial_metrics_agent.py @@ -12,7 +12,7 @@ import yfinance as yf from strands import Agent, tool from strands.models.bedrock import BedrockModel -from strands_tools import think, http_request +from strands_tools import http_request @tool @@ -129,7 +129,7 @@ def create_financial_metrics_agent(): - Risk Assessment """, model=BedrockModel(model_id="us.anthropic.claude-opus-4-6-v1"), - tools=[get_financial_metrics, http_request, think], + tools=[get_financial_metrics, http_request], ) diff --git a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/stock_price_agent.py b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/stock_price_agent.py index 93020e00e..a2c77eb7b 100644 --- a/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/stock_price_agent.py +++ b/python/04-industry-use-cases/finance/finance-assistant-swarm-agent/stock_price_agent.py @@ -12,7 +12,7 @@ import yfinance as yf from strands import Agent, tool from strands.models.bedrock import BedrockModel -from strands_tools import think, http_request +from strands_tools import http_request @tool @@ -98,7 +98,7 @@ def create_stock_price_agent(): 3. Key Metrics Summary """, model=BedrockModel(model_id="us.anthropic.claude-opus-4-6-v1"), - tools=[get_stock_prices, http_request, think], + tools=[get_stock_prices, http_request], ) diff --git a/python/04-industry-use-cases/finance/genai-powered-financial-advisor-tools/application/mcp_server_kb.py b/python/04-industry-use-cases/finance/genai-powered-financial-advisor-tools/application/mcp_server_kb.py index a36ee9de9..d99a282a9 100644 --- a/python/04-industry-use-cases/finance/genai-powered-financial-advisor-tools/application/mcp_server_kb.py +++ b/python/04-industry-use-cases/finance/genai-powered-financial-advisor-tools/application/mcp_server_kb.py @@ -10,7 +10,6 @@ import yaml from strands import Agent, tool -from strands_tools import current_time, retrieve from mcp.server.fastmcp import FastMCP diff --git a/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/email_assistant.py b/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/email_assistant.py index fe3798720..6c78c2a41 100644 --- a/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/email_assistant.py +++ b/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/email_assistant.py @@ -14,7 +14,7 @@ # Third-party imports from strands import Agent, tool from strands.models import BedrockModel -from strands_tools import editor, think +from strands_tools import editor # Import your existing 02-agents # Assuming these are in the same directory or in your Python path @@ -84,7 +84,6 @@ def create_email_assistant(kb_id: str = None, region: str = "us-west-2") -> Agen # http_request, retrieve_from_kb, generate_image_nova, - think, ], ) diff --git a/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/image_generation_agent.py b/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/image_generation_agent.py index 1659c1789..9da24f966 100644 --- a/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/image_generation_agent.py +++ b/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/image_generation_agent.py @@ -17,8 +17,6 @@ from strands import Agent, tool from strands.models import BedrockModel -from strands_tools import think - # Create directory for saved images if it doesn't exist SAVE_DIR = "generated_images" @@ -113,7 +111,7 @@ def create_image_agent() -> Agent: Always confirm actions and provide clear feedback about what was done.""", model=BedrockModel(model_id="us.amazon.nova-pro-v1:0", region="us-east-1"), - tools=[generate_image_nova, think], + tools=[generate_image_nova], ) diff --git a/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/kb_rag.py b/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/kb_rag.py index e7b3ce792..6fffc3451 100644 --- a/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/kb_rag.py +++ b/python/04-industry-use-cases/productivity/multi-modal-email-assistant-agent/kb_rag.py @@ -12,7 +12,7 @@ from strands import Agent from strands.models import BedrockModel -from strands_tools import retrieve, think +from strands_tools import retrieve # ======== DEFAULT CONFIGURATION ======== # Default values (will be used if not provided as command-line arguments) @@ -81,7 +81,7 @@ def create_analyzer_agent(region: str) -> Agent: Focus on accuracy and clarity in your responses. When information is incomplete or uncertain, acknowledge the limitations. Organize your response in a structured format with clear sections when appropriate.""", model=BedrockModel(model_id="us.amazon.nova-pro-v1:0", region=region), - tools=[retrieve, think], + tools=[retrieve], ) diff --git a/python/04-industry-use-cases/productivity/personal-assistant/README.md b/python/04-industry-use-cases/productivity/personal-assistant/README.md index 100b40f95..a7aa220a2 100644 --- a/python/04-industry-use-cases/productivity/personal-assistant/README.md +++ b/python/04-industry-use-cases/productivity/personal-assistant/README.md @@ -13,7 +13,7 @@ This sample implements a personal assistant agent using Strands' [agents as tool - **List All Appointments**: View all scheduled appointments in a formatted list - **Update Appointments**: Modify existing appointments by ID - **Daily Agenda**: Get a formatted agenda for any specific date -- **Time Awareness**: Built-in current time functionality +- **Time Awareness**: A `current_time` tool defined in the sample ### 💻 Coding Assistant - **Python REPL**: Execute Python code in a REPL environment with PTY support and state persistence. diff --git a/python/04-industry-use-cases/productivity/personal-assistant/calendar_assistant.py b/python/04-industry-use-cases/productivity/personal-assistant/calendar_assistant.py index 12e8ea0e2..8b81fa385 100644 --- a/python/04-industry-use-cases/productivity/personal-assistant/calendar_assistant.py +++ b/python/04-industry-use-cases/productivity/personal-assistant/calendar_assistant.py @@ -1,7 +1,7 @@ import os +from datetime import datetime, timezone from strands import Agent, tool from strands.models import BedrockModel -from strands_tools import current_time from calendar_tools import create_appointment, get_agenda, list_appointments, update_appointment from constants import SESSION_ID @@ -9,6 +9,12 @@ os.environ["STRANDS_TOOL_CONSOLE_MODE"] = "enabled" +@tool +def current_time() -> str: + """Get the current UTC date and time in ISO 8601 format.""" + return datetime.now(timezone.utc).isoformat() + + @tool def calendar_assistant(query: str) -> str: """ diff --git a/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/README.md b/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/README.md index cb75908a9..f4eb0c815 100644 --- a/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/README.md +++ b/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/README.md @@ -9,7 +9,7 @@ AWS Assistant is a sophisticated multi-agent system designed to provide comprehe |Feature |Description | |--------------------|---------------------------------------------------| |Agent Structure |Multi-agent architecture | -|Native Tools |think, file_write, python_repl, shell | +|Native Tools |file_write, python_repl, shell | |Custom Agents |aws_documentation_researcher, graph_creater, aws_cost_assistant| |MCP Servers |[AWS Cost Explorer](https://github.com/aarora79/aws-cost-explorer-mcp-server), [AWS Documentation](https://awslabs.github.io/mcp/servers/aws-documentation-mcp-server/) | |Model Provider |Amazon Bedrock | diff --git a/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/main.py b/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/main.py index 651097e0f..a622b17fe 100644 --- a/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/main.py +++ b/python/04-industry-use-cases/software-engineering/aws-assistant-mcp/main.py @@ -20,8 +20,6 @@ from aws_documentation_researcher import aws_documentation_researcher from graph_creater import graph_creater from strands import Agent -from strands_tools import think - # Interactive mode when run directly SUPERVISOR_AGENT_PROMPT = """ @@ -52,7 +50,7 @@ supervisor_agent = Agent( system_prompt=SUPERVISOR_AGENT_PROMPT, # stream_handler=None, - tools=[aws_documentation_researcher, graph_creater, aws_cost_assistant, think], + tools=[aws_documentation_researcher, graph_creater, aws_cost_assistant], ) diff --git a/python/04-industry-use-cases/software-engineering/aws-audit-assistant/ai_assistant.py b/python/04-industry-use-cases/software-engineering/aws-audit-assistant/ai_assistant.py index 6a7d06535..65682a297 100644 --- a/python/04-industry-use-cases/software-engineering/aws-audit-assistant/ai_assistant.py +++ b/python/04-industry-use-cases/software-engineering/aws-audit-assistant/ai_assistant.py @@ -1,8 +1,8 @@ ## ⚠️⚠️ PLEASE READ : The script agent creates and executes the script that may perform changes to your environment, always execute it from a sandbox (sample attached in sandbox folder) with readonly permissions to avoid any issues ⚠️⚠️ -from strands import Agent,tool +from strands import Agent, tool from strands.models.bedrock import BedrockModel -from strands_tools import calculator, file_read, shell,http_request,python_repl, editor, journal +from strands_tools import file_read, shell, http_request, python_repl, editor, journal from aws_document_agent import doc_retrieve as doc_agent from strands_boto_agent import code_assistant import os diff --git a/python/04-industry-use-cases/software-engineering/aws-audit-assistant/strands_boto_agent.py b/python/04-industry-use-cases/software-engineering/aws-audit-assistant/strands_boto_agent.py index 1dcf63524..87e408f24 100644 --- a/python/04-industry-use-cases/software-engineering/aws-audit-assistant/strands_boto_agent.py +++ b/python/04-industry-use-cases/software-engineering/aws-audit-assistant/strands_boto_agent.py @@ -1,9 +1,9 @@ ## ⚠️⚠️ PLEASE READ : The script agent creates and executes the script that may perform changes to your environment, always execute it from a sandbox (sample attached in sandbox folder) with readonly permissions to avoid any issues ⚠️⚠️ -from strands import Agent,tool +from strands import Agent, tool from strands.models.bedrock import BedrockModel -from strands_tools import calculator, file_read, shell,http_request,python_repl, editor, journal +from strands_tools import file_read, shell, http_request, python_repl, editor, journal from aws_document_agent import doc_retrieve as doc_agent import os os.environ["BYPASS_TOOL_CONSENT"] = "true" diff --git a/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/README.md b/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/README.md index 6c64bda10..42c642126 100644 --- a/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/README.md +++ b/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/README.md @@ -14,9 +14,9 @@ A multi-agent system to optimize SQL queries on a SQLite database, simulating a | Feature | Description | |-------------------|------------------------------------------------------------------------------| | **Agent Structure** | Multi-agent architecture - Sequential | -| **Native Tools** | `calculator` | +| **Native Tools** | none | | **Custom Agents** | `Analyzer Agent`, `Rewriter Agent`, `Validator Agent` | -| **Custom Tools** | `get_query_execution_plan`, `suggest_optimizations`, `validate_query_cost` | +| **Custom Tools** | `get_query_execution_plan`, `suggest_optimizations`, `validate_query_cost`, `calculator` | | **Model Provider** | Amazon Bedrock | --- diff --git a/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/main.py b/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/main.py index 261c6a937..f4f694f5a 100644 --- a/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/main.py +++ b/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/main.py @@ -4,12 +4,13 @@ Main entry point with CLI interface. """ +import operator + from botocore.exceptions import NoCredentialsError, ProfileNotFound from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter -from strands import Agent -from strands_tools import calculator +from strands import Agent, tool from strands.models import BedrockModel from typing import Dict, Any from utils.prompts import analyzer_prompt, rewriter_prompt, validator_prompt @@ -27,6 +28,27 @@ import sqlite3 import uuid +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) + + # Initialize OpenTelemetry trace.set_tracer_provider(TracerProvider()) tracer = trace.get_tracer(__name__) diff --git a/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/pyproject.toml b/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/pyproject.toml index b0004d448..1e6a1030f 100644 --- a/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/pyproject.toml +++ b/python/04-industry-use-cases/software-engineering/data-warehouse-optimizer/pyproject.toml @@ -5,6 +5,5 @@ description = "Multi-Agent Data Warehouse Query Optimizer using SQLite and AWS B requires-python = ">=3.10" dependencies = [ "strands-agents", - "strands-agents-tools", "boto3", ] diff --git a/python/07-ux-demos/slack-assistant/app.py b/python/07-ux-demos/slack-assistant/app.py index dd6b33242..e11a80078 100644 --- a/python/07-ux-demos/slack-assistant/app.py +++ b/python/07-ux-demos/slack-assistant/app.py @@ -1,3 +1,5 @@ +import operator + import logging import os import sys @@ -13,7 +15,26 @@ from strands.hooks import AfterToolCallEvent, BeforeToolCallEvent from strands.models import BedrockModel from strands.types.content import Message -from strands_tools import calculator + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) logging.basicConfig(stream=sys.stdout, level=logging.INFO) @@ -47,7 +68,7 @@ def start_assistant_thread( say("How can I help you?") prompts: List[Dict[str, str]] = [ - {"title": "Use a calculator", "message": "What is sin(0.4487)?"}, + {"title": "Use a calculator", "message": "What is 144 ** 0.5?"}, {"title": "Set a timer", "message": "Set a timer for 5 seconds"}, ] diff --git a/python/07-ux-demos/streamlit-template/README.md b/python/07-ux-demos/streamlit-template/README.md index 13d618223..6ea943ecc 100644 --- a/python/07-ux-demos/streamlit-template/README.md +++ b/python/07-ux-demos/streamlit-template/README.md @@ -133,8 +133,8 @@ streamlit run app_streaming.py --server.port 8080 |Feature |Description | |--------------------|-----------------------------------------------------------| -|Native tools used |current_time, calculator | -|Custom tools created|create_appointment, list_appointments, update_appointments | +|Native tools used |none | +|Custom tools created|current_time, calculator, create_appointment, list_appointments, update_appointments | |Agent Structure |Single agent architecture | diff --git a/python/07-ux-demos/streamlit-template/docker_app/app.py b/python/07-ux-demos/streamlit-template/docker_app/app.py index 5cca74039..8c2e0a30a 100644 --- a/python/07-ux-demos/streamlit-template/docker_app/app.py +++ b/python/07-ux-demos/streamlit-template/docker_app/app.py @@ -1,15 +1,43 @@ +import operator +from datetime import datetime, timezone + import streamlit as st import json from utils.auth import Auth from config_file import Config -from strands import Agent +from strands import Agent, tool from strands.models import BedrockModel import tools.list_appointments import tools.update_appointment import tools.create_appointment -from strands_tools import calculator, current_time + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) + + +@tool +def current_time() -> str: + """Get the current UTC date and time in ISO 8601 format.""" + return datetime.now(timezone.utc).isoformat() # Initialize session state for conversation history if "messages" not in st.session_state: diff --git a/python/07-ux-demos/streamlit-template/docker_app/app_streaming.py b/python/07-ux-demos/streamlit-template/docker_app/app_streaming.py index 4e20e2dbf..24747a5b0 100644 --- a/python/07-ux-demos/streamlit-template/docker_app/app_streaming.py +++ b/python/07-ux-demos/streamlit-template/docker_app/app_streaming.py @@ -1,15 +1,43 @@ +import operator +from datetime import datetime, timezone + import asyncio import streamlit as st from utils.auth import Auth from config_file import Config -from strands import Agent +from strands import Agent, tool from strands.models import BedrockModel import tools.list_appointments import tools.update_appointment import tools.create_appointment -from strands_tools import calculator, current_time + +_OPS = { + "+": operator.add, + "-": operator.sub, + "*": operator.mul, + "/": operator.truediv, + "**": operator.pow, +} + + +@tool +def calculator(a: float, b: float, op: str) -> float: + """Apply an arithmetic operator to two numbers. + + Args: + a: Left operand. + b: Right operand. + op: One of "+", "-", "*", "/", "**". + """ + return _OPS[op](a, b) + + +@tool +def current_time() -> str: + """Get the current UTC date and time in ISO 8601 format.""" + return datetime.now(timezone.utc).isoformat() # Initialize session state for conversation history if "messages" not in st.session_state: diff --git a/python/07-ux-demos/streamlit-template/docker_app/requirements.txt b/python/07-ux-demos/streamlit-template/docker_app/requirements.txt index bbb51de60..75c49fab3 100644 --- a/python/07-ux-demos/streamlit-template/docker_app/requirements.txt +++ b/python/07-ux-demos/streamlit-template/docker_app/requirements.txt @@ -2,5 +2,4 @@ streamlit==1.45.1 boto3==1.38.18 streamlit-cognito-auth==1.3.1 strands-agents==1.23.0 -strands-agents-tools>=0.1.1 urllib3>=2.6.0 \ No newline at end of file diff --git a/python/07-ux-demos/video-games-sales-assistant/README.md b/python/07-ux-demos/video-games-sales-assistant/README.md index 966d90f6f..d880542c9 100644 --- a/python/07-ux-demos/video-games-sales-assistant/README.md +++ b/python/07-ux-demos/video-games-sales-assistant/README.md @@ -46,12 +46,10 @@ The solution deploys the following AWS services through AWS CDK: - **Application Load Balancer and Fargate Container for Strands Agent**: Powers the ***Data Analyst Assistant*** that answers questions by generating SQL queries using Claude Sonnet 4.6 - Contains all the logic for agent configuration and tools - - Built-in tools include: - - Custom tools: - - execute_sql_query - - get_tables_information - - Strands tool: - - current_time + - Custom tools defined in the sample: + - execute_sql_query + - get_tables_information + - current_time - **Amazon Aurora PostgreSQL Serverless v2**: Stores the video game sales data with Data API enabled for secure access - **Amazon ECS on Fargate**: Hosts the Strands Agent service with container insights and auto-scaling capabilities - **Amazon DynamoDB**: Two tables for tracking users' conversations and raw query results @@ -79,7 +77,7 @@ The **user interaction workflow** operates as follows: - The web application sends user business questions to the agent built with Strands Agents SDK - The agent (powered by Claude Sonnet 4.6) processes natural language and determines when to execute database queries -- The agent's built-in tools execute SQL queries against the Aurora PostgreSQL database and formulate an answer to the question +- The agent's tools execute SQL queries against the Aurora PostgreSQL database and formulate an answer to the question - After the agent's response is received by the web application, the raw data query results are retrieved from the DynamoDB table to display both the answer and the corresponding records - For chart generation, the application invokes a model (powered by Claude Sonnet 4.6) to analyze the agent's answer and raw data query results to generate the necessary data to render an appropriate chart visualization @@ -89,8 +87,8 @@ The **user interaction workflow** operates as follows: | Feature | Description | |----------|----------| -| Native Tools | current_time - A built-in Strands tool that provides the current date and time information based on user's timezone. | -| Custom Tools | get_tables_information - A custom tool that retrieves metadata about the database tables, including their structure, columns, and relationships, to help the agent understand the database schema.
execute_sql_query - A custom tool that allows the agent to run SQL queries against the PostgreSQL database based on the user's natural language questions, retrieving the requested data for analysis. | +| Native Tools | none | +| Custom Tools | current_time - A tool defined in the sample that returns the current UTC date and time in ISO 8601 format.
get_tables_information - A custom tool that retrieves metadata about the database tables, including their structure, columns, and relationships, to help the agent understand the database schema.
execute_sql_query - A custom tool that allows the agent to run SQL queries against the PostgreSQL database based on the user's natural language questions, retrieving the requested data for analysis. | | Model Provider | Amazon Bedrock | ## Deployment Instructions diff --git a/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/requirements.txt b/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/requirements.txt index 6055bb505..bf6d89435 100644 --- a/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/requirements.txt +++ b/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/requirements.txt @@ -1,5 +1,4 @@ strands-agents==1.13.0 -strands-agents-tools==0.2.12 fastapi==0.120.1 uvicorn==0.38.0 pydantic==2.12.3 diff --git a/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/src/app.py b/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/src/app.py index 2e24239da..398780482 100644 --- a/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/src/app.py +++ b/python/07-ux-demos/video-games-sales-assistant/cdk-strands-data-analyst-assistant/docker/src/app.py @@ -1,5 +1,4 @@ from strands import Agent, tool -from strands_tools import current_time from strands.models import BedrockModel from fastapi import FastAPI, HTTPException, Header from fastapi.responses import StreamingResponse @@ -9,6 +8,7 @@ import boto3 import json from uuid import uuid4 +from datetime import datetime, timezone import os # Import my tools @@ -50,6 +50,13 @@ allow_headers=["*"], ) + +@tool +def current_time() -> str: + """Get the current UTC date and time in ISO 8601 format.""" + return datetime.now(timezone.utc).isoformat() + + def load_system_prompt(): """ Load the system prompt from the instructions.txt file. diff --git a/python/08-edge/strands-spot-agent/agent.py b/python/08-edge/strands-spot-agent/agent.py index bd33d5a2e..afba60488 100644 --- a/python/08-edge/strands-spot-agent/agent.py +++ b/python/08-edge/strands-spot-agent/agent.py @@ -12,8 +12,6 @@ from dotenv import load_dotenv from strands import Agent -from strands_tools import think - # Import spot tools directly from spot_mcp_server import ( connect_to_robot, @@ -275,10 +273,9 @@ async def main(): robot_dock, robot_undock, robot_get_dock_status, - think, ] - print(f"\n✅ Loaded {len(tool_list) - 1} robot tools") + print(f"\n✅ Loaded {len(tool_list)} robot tools") print(f"🤖 Using model: {MODEL}") try: diff --git a/python/08-edge/strands-spot-agent/requirements.txt b/python/08-edge/strands-spot-agent/requirements.txt index 778f8c7e8..e84dfc912 100644 --- a/python/08-edge/strands-spot-agent/requirements.txt +++ b/python/08-edge/strands-spot-agent/requirements.txt @@ -9,7 +9,6 @@ httpx>=0.24.0 pydantic>=2.0.0 mcp>=0.1.0 strands-agents>=1.0.0,<2.0.0 -strands-agents-tools>=0.0.1 # AWS and Nova Sonic boto3>=1.26.0