SmartStore AI — Phase 7 Implementation Guide

Agent Layer & Tool Calling

What got built

backend/app/agent.py             — real ReAct loop, TOOLS definitions, TOOL_FUNCTIONS
backend/app/api/agent_ask.py       — POST /ask/agent, alongside (not replacing) Phase 3's /ask
backend/tests/test_agent.py

The single most important design decision in this phase

store_id is not a field the model can supply. Look at the TOOLS schema in app/agent.pyget_product_location's input_schema only has product_name. store_id is injected server-side, from the authenticated request's verified context, on every tool call, unconditionally overriding anything that happened to be in the model's call.input. This matters because the model's tool-call arguments are effectively LLM output — and Volume 3, Chapter 11's rule is explicit: never let security-relevant values (which store's data to access) come from the model, only from verified context.

This is directly tested, not just claimed: test_agent_injects_store_id_even_if_model_tries_to_supply_a_different_one constructs a fake tool call that does include a store_id (an "attacker-supplied" one), and confirms the function that actually runs receives the real, verified one instead.

Other key decisions

/ask/agent exists alongside /ask, not in place of it. A simple grounded Q&A call (Phase 3) and a full multi-step agent (this phase) have different latency and cost profiles — Volume 1, Chapter 1's chatbot-vs-agent distinction is a real architectural choice, not just a teaching device, and a real product reasonably wants both available for different request types.

max_steps is enforced and tested directly, not just present in the code. test_agent_stops_after_max_steps_to_prevent_runaway_loop feeds the agent a fake client that always wants to call another tool, confirming the loop actually stops at the limit rather than running forever — this is the kind of bug that's easy to write code "for" without ever confirming it actually works under the failure condition it's meant to guard against.

Verified test results

tests/test_agent.py::test_agent_answers_directly_with_no_tool_call_needed PASSED
tests/test_agent.py::test_agent_calls_tool_then_produces_final_answer PASSED
tests/test_agent.py::test_agent_injects_store_id_even_if_model_tries_to_supply_a_different_one PASSED
tests/test_agent.py::test_agent_stops_after_max_steps_to_prevent_runaway_loop PASSED
tests/test_agent.py::test_ask_agent_endpoint_requires_auth PASSED

Full suite: 26 passed

What's next

Phase 8 — Streaming, Voice & Image Input adds SSE streaming to both /ask endpoints, plus the voice and image input modalities from Volume 6 of the bootcamp, on top of this same auth/RBAC/agent foundation.