Floor 2: The Vending Machines

Floor 2: The Vending Machines

Files on this floor: 2_vended_tools/agent_with_vended_tools.py, 2_vended_tools/bonus_quest.py

Cordula CORDULA’S LOG, FLOOR 2. Below the lobby the water shallowed into a meadow of eelgrass, crab country, and the crabs do not like noise. Barnaby wanted to know what he was. Not philosophically; tactically. What can a giant octopus do, by the book? The vending machines down here sold tools, and one of them could look things up. He read the old monster manual entry on his own species and was offended for ten minutes. Then a scripter named Kiro offered to run any command we wanted, no questions asked. I do not let anyone run a command I have not read. That is the second machine on this floor. Somewhere in the sand under the eelgrass, something big and pale started to dig its way up. That was Shelly.

System AI System AI: “Floor 2. The vending machines are open. Everything on offer ships with the SDK, nothing is free of consequences, and the optional shell tool will run exactly what you approve. Approve with care. The sponsors are hoping you will not.”

Floor Objective

Tools are the primary mechanism for extending agent capabilities, enabling them to perform actions beyond text generation. Tools allow agents to interact with external systems, access data, and manipulate their environment. On this floor, you’ll use your first vended tool, the name Strands gives to the tools that ship with the SDK, by adding the http_request tool to your agent, so your Narrator can look up real creature stat blocks on a public role-playing game API.

Make sure you are at the root of Floor 2 in your terminal:

cd aiRPG-seattle-dungeon-crawl/2_vended_tools

Open and modify the agent_with_vended_tools.py file.

Your Arsenal: Vended Tools

System AI System AI: “Vended tools ship in strands.vended_tools. No pip install, no shopping, no excuses. The shell tool runs exactly what you approve, and the audience adores a Crawler who approves everything.”

The Strands SDK ships with a set of ready-to-use tools, the vended tools. They live in strands.vended_tools, so there is nothing extra to install. Here are some of them:

  • http_request: calls external APIs (GET, POST, …)
  • notebook: keeps persistent notes in the agent’s state
  • file_editor: views, creates and edits files
  • shell: runs shell commands
  • web_fetch: fetches a web page and answers a question about it
  • handoff_to_user: pauses to ask the user a question

The complete list is on the Vended Tools page of the Strands docs.

Cordula CORDULA: Six machines in a row, humming in the eelgrass. I read every label before I touched one, the way you check a parts bin before you trust it. Barnaby pointed two arms at the one that looks things up. “That one, Sergeant. I wish to know what the surface world thinks I am.”

Step 1: Equip Your Agent with http_request

Item ITEM ACQUIRED: [http_request]

Calls external APIs on your agent’s behalf. Rarity: Common. Comes with the Open5e API pre-bookmarked, because the System refuses to invent a stat block in front of a live audience.

# TODO: Step 1 - Import http_request from strands.vended_tools
# TODO: Step 1 - Add the http_request tool to your agent

Import the http_request tool from strands.vended_tools, then pass it to your agent’s tools parameter: see Adding Tools to Agents in the Strands docs. The system prompt already tells your Narrator where to find creatures: the free Open5e API, which serves the System Reference Document 5.1 under the Creative Commons Attribution 4.0 license. The HTTP request page describes what the tool can do.

In the file, tools=[...] holds only the TODO comment. Replace the empty list with one that holds the tool.

Show me the code for Step 1
from strands import Agent
# TODO: Step 1 - Import http_request from strands.vended_tools
from strands.vended_tools import http_request
agent = Agent(
    model="us.amazon.nova-2-lite-v1:0",  # Amazon Nova 2 Lite, US cross-Region inference profile
    # TODO: Step 1 - Add the http_request tool to your agent
    tools=[http_request],
    system_prompt="""...""",
)

A vended tool is a ready-made Strands tool object: import it and put it in the list, with no parentheses after its name.

Step 2: Test Your Agent

Floor boss FLOOR BOSS: Barnaby’s homework. The party leader wants to know how the surface world’s monster manuals rated his species, and he has a doctorate’s worth of opinions ready. Your agent must look it up instead of guessing. Barnaby will check.

Once you’ve completed both TODOs, run your script:

python agent_with_vended_tools.py

Your agent will:

  • Receive the question “Barnaby is a Giant Pacific Octopus. How do the old monster manuals say a giant octopus hides underwater, and what does its Ink Cloud do?”
  • Determine that it needs to use the http_request tool
  • Call the API at https://api.open5e.com/v2/creatures/srd_giant-octopus/
  • Answer from the data it received: Underwater Camouflage gives advantage on Dexterity (Stealth) checks underwater, and Ink Cloud fills a 20-foot radius that stays heavily obscured for 1 minute, after which the octopus can Dash as a bonus action

This demonstrates that your agent can autonomously select and use tools to answer questions.

Check: the terminal shows Tool #1: http_request before the answer, and the answer quotes the 20-foot radius and the 1 minute of Ink Cloud. Those numbers come from the API. An agent without the tool would have to guess them.

you seeit meansfix
ImportError: cannot import name 'http_request'a typo, or an older SDKcopy the import from the Show me block; uv run python -c "import importlib.metadata as m; print(m.version('strands-agents'))" must print 1.61 or later, otherwise run uv sync
an answer with no Tool #1 linethe tool is not on the agentcheck the second TODO: tools=[http_request]
Tool #1: http_request, then a connection error or a timeoutyour network cannot reach Open5eopen https://api.open5e.com/v2/creatures/srd_giant-octopus/ in a browser; on a corporate network, set HTTPS_PROXY
AccessDeniedException or ExpiredTokenthe model call failed, not the toolrun the check in Floor 0, Step 7

Cordula CORDULA: The answer came back with numbers in it, and every one had a source. Barnaby read the stat block twice. “Advantage on stealth. Correct. A twenty-foot ink cloud. Accurate, if unambitious.” Then, quieter: “They wrote me down as a monster, Sergeant.” I told him it was a game manual from before anybody had met him. He went red for ten minutes. Then he asked how many other things the machine could look up.

System AI SYSTEM DESIGN, LAYER 2: OUTSIDE KNOWLEDGE. A System that makes up facts loses its readers the first time a number contradicts itself. Giving the agent a tool means it looks things up and quotes the source instead of guessing. Barnaby’s own abilities in the cast sheet (Chromatophore Stealth, Ink Cloud) are built on exactly what this API returns, adapted to the dance floor. See The System.

Bonus Room: The Multi-Tool Challenge (optional)

Ready to go deeper? Open 2_vended_tools/bonus_quest.py. Kiro the Doomsday Scripter, a crawler whose class treats code as demolition magic, will write a Fibonacci script to a file and run it: two tools and one safeguard, wired the same way as the main floor. Each step below has two TODOs in the code: the import at the top of the file, and its use in the agent.

Warning SYSTEM WARNING: Windows users: the shell tool runs commands through sh, and file_editor expects POSIX paths (starting with /), so this bonus room does not run on native Windows. To try it on Windows, run it inside WSL (Windows Subsystem for Linux).

Step 1: Equip the Tools

# TODO: Step 1 - Import shell and file_editor from strands.vended_tools
# TODO: Step 1 - Add the shell and file_editor tools to your agent

Both are vended tools: file_editor writes the scroll, shell casts it. Import them, then pass them in the agent’s tools parameter, exactly like http_request in the main floor: see Adding Tools to Agents, and the pages for shell and file editor.

Show me the code for Step 1
# TODO: Step 1 - Import shell and file_editor from strands.vended_tools
from strands.vended_tools import shell, file_editor
    # TODO: Step 1 - Add the shell and file_editor tools to your agent
    tools=[shell, file_editor],

The two import TODOs sit together at the top of the file, and the two agent TODOs sit together inside Agent(...). Each answer goes under its own comment, or under the pair: the solution branch puts both imports after the second import TODO.

Cordula CORDULA: Kiro the Doomsday Scripter had a terminal strapped to his chest and a grin I have seen on boot privates holding fireworks. He wanted a pen and a match: something to write a file, something to run it. I gave him both. I did not give him permission yet.

Step 2: Add the Safeguard

Item ITEM ACQUIRED: [HumanInTheLoop]

An intervention that makes every tool call wait for your y/n. Rarity: Uncommon. Side effect: you become personally responsible for everything that happens next.

# TODO: Step 2 - Import HumanInTheLoop from strands.vended_interventions.hitl
# TODO: Step 2 - Ask for your approval before each tool call with HumanInTheLoop in stdio mode

Writing files and running commands change your system. Strands lets you gate tool calls behind your approval with an intervention: import HumanInTheLoop, then pass HumanInTheLoop(ask="stdio") in the agent’s interventions parameter, as shown in Stdio Mode on the Human in the loop page. Every tool call now pauses and asks for your permission in the terminal:

Approve "file_editor"?
  Input: {"command": "create", "path": ".../fibonacci_scroll.py", ...} (y/n):

Type y and press Enter to allow the tool to execute, or n to refuse. Without this step, the agent writes files and runs commands without asking you anything: try it once with Step 2 left out to see the difference.

Show me the code for Step 2
# TODO: Step 2 - Import HumanInTheLoop from strands.vended_interventions.hitl
from strands.vended_interventions.hitl import HumanInTheLoop
    # TODO: Step 2 - Ask for your approval before each tool call with HumanInTheLoop in stdio mode
    interventions=[HumanInTheLoop(ask="stdio")],

interventions takes a list, like tools. Unlike a vended tool, HumanInTheLoop is a class: call it, with ask="stdio", to get the intervention.

Cordula CORDULA: This is the rule I brought down from the surface: nobody runs a command I have not read. Not Kiro, not the System, not the octopus. Barnaby asked whether that applied to him. I said especially to him. He considered this for a while, then turned a pleased shade of brown. He likes knowing where the lines are.

Step 3: Cast the Spell

python bonus_quest.py

Approve each call as it comes:

  • Approve "file_editor"?: Kiro writes fibonacci_scroll.py in the floor folder. Type y.
  • Approve "shell"?: Kiro casts the scroll, usually python3 fibonacci_scroll.py, sometimes after a cd into the folder. Type y for each shell call.
  • Kiro reports the first ten Fibonacci numbers.

Try n on one of the calls to see how the agent reacts to a refusal.

Check: fibonacci_scroll.py now sits in 2_vended_tools/, and Kiro reports the first ten Fibonacci numbers, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 (some runs start at 1 instead of 0). Run python fibonacci_scroll.py yourself: the scroll prints the same numbers.

you seeit meansfix
no Approve prompt at all, and the file appears anywaythe intervention is not on the agentcheck Step 2: interventions=[HumanInTheLoop(ask="stdio")]
ModuleNotFoundError: No module named 'strands.vended_interventions'an older SDKuv sync, then check the version as in Step 2 of the main floor
file_editor refuses the paththe path is not absolute, or you are on native Windowsrun the script from 2_vended_tools/; on Windows, use WSL (see the warning above)
the scroll is written, then the shell call fails with python3: not foundyour system calls Python pythontype n on that call: Kiro usually retries with python. If not, add “run it with python” to the request at the bottom of bonus_quest.py

Cordula CORDULA: I said no to the first command Kiro tried, on purpose, to see what he would do. He sulked, rewrote it, and asked again. That is the whole point of the machine. Then the sand under my boots started to move, slowly, the way a tide moves, and something pale and the size of a loaf of bread pushed up out of the eelgrass and sighed sea mist at me. Shelly had arrived. He has never once let go of the floor since.

System AI System AI: “allowed_tools=[”*"] removes every prompt. The sponsors call it brave. The System calls it content."

  • Approval prompts: tools run with the permissions of your Python process. With HumanInTheLoop, nothing that alters your system happens without your explicit approval.
  • Letting some tools through: allowed_tools=["file_editor"] lets a tool run freely while the others still ask. Use ["*"] to disable the prompts entirely, for testing only.

Side Passages (optional)

Cordula CORDULA: The eelgrass has more machines than the six on the main row, and Kiro has more scrolls than one.

  • The Tide Table, sidequest: today’s real Seattle tides from NOAA, and a ruling on whether the Estuary dance floor is underwater
  • The Sandbox Tide Pool, sidequest: Kiro’s scroll cast inside a Docker sandbox instead of your own shell
  • The Policy Gatekeeper, boss battle: a Cedar policy and a risk classifier in front of Kiro, so you only see the risky calls
  • Ask the Player, sidequest: the Narrator stops mid-turn to ask you which Move Call to make

Floor Clear

Floor cleared, Crawler. You’ve equipped your agent with the http_request vended tool, and it can now decide on its own when to use it.

Loot you’re keeping:

  • How to import a vended tool and add it to your agent
  • How an agent autonomously decides when to use a tool
  • Tool consent and safety (covered with the bonus room’s HumanInTheLoop intervention)

Stairwell Stairwell: Journey to Floor 3 where you’ll create custom tools for your specific use cases.

Achievement NEW ACHIEVEMENT UNLOCKED!

[VENDED, NOT EARNED]

Reward: You received a [Bronze Box]. Inside: an http_request tool, a stern reminder about HumanInTheLoop, and a coupon for one (1) apology to your own filesystem.

System AI System AI: “Your agent now decides on its own when to reach for a tool. The sponsors call this “emergent behavior.” I call it Tuesday.”

View this file on GitHub commit 4018746, edited in the workshop repository only