This document summarizes the multi-agent system implemented in project_starter_Elena.py, the evaluation status, strengths and areas for improvement, and next steps to obtain a full evaluation run producing test_results.csv.
-
The project implements a small multi-agent system for a fictional paper supplier (Munder Difflin).
-
Agents are implemented as
ToolCallingAgentsubclasses from thesmolagentsframework and use small database-backed helper functions to perform tasks. -
Agents and responsibilities:
a. InventoryAgent
- Tools:
check_inventoryandget_item_price(decorated with@tool),get_all_inventoryandget_stock_level(wrapped as smolagents functions). - Responsible for inspecting stock levels and answering inventory queries.
b. QuotingAgent
- Tools:
generate_quoteandget_item_price(decorated with@tool),get_all_inventoryandget_stock_level(wrapped as smolagents functions). - Responsible for creating customer quotes based on inventory and pricing.
c. OrderingAgent
- Tools:
place_order(decorated with@tool) andget_cash_balance(wrapped as smolagent function). - Responsible for placing orders (sales or stock replenishment) and updating transactions.
d. OrchestrationAgent
- Instantiates the three worker agents and coordinates end-to-end request handling: inventory check -> quote -> order.
- Tools:
-
Tools (helper functions):
a.
get_all_inventory(as_of_date)— returns inventory snapshot as a dict.b.
get_stock_level(item_name, as_of_date)— returns a DataFrame with current stock for a single item.c.
get_item_price(item_name),check_inventory(request, as_of_date),generate_quote(request, inventory_check),place_order(quote_details, request_date)— provide the business logic for quoting and ordering. -
Data & DB:
a. Uses an SQLite DB
munder_difflin.dbcreated via SQLAlchemy'screate_engine(not provided in this repo).b. On
init_database()the script createstransactions,inventory,quotes, andquote_requeststables from CSVs and seeds inventory. -
Main evaluation flow with
run_test_scenarios():-
Initializes DB (calls
init_database). -
Reads
quote_requests_sample.csvand iterates requests chronologically. -
For each request, uses
OrchestrationAgent.handle_requestto process the request and appends a result entry. -
Saves results to
test_results.csv.
-
It is necessary to install requirements.txt but also smolagents before running the code.
What we can find in test_results.csv when we run the evaluation successfully
-
Columns (produced by
run_test_scenarios()):request_id,request_date,cash_balance,inventory_value,response. -
Each
responseis a dictionary-like object containinginventory_check,quote_details, andorder_confirmationreturned by the orchestration agent for that request.
How to reproduce evaluation locally (bash):
- From the workspace root (where
project_starter_Elena.pyis located), I created a virtual environment with Udacity's OPENAI_API_KEY, and installed dependencies:
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install pandas numpy python-dotenv sqlalchemy smolagents- Ensured the CSV files expected by the script were present in the same folder:
quote_requests.csvquotes.csvquote_requests_sample.csv
- Ran the evaluation:
python3 project_starter_Elena.py- After a successful run we find
test_results.csvin the same folder.
Quick verification steps
- Confirmed
munder_difflin.dbappeared (SQLite DB; not provided in this repo). - Inspected
test_results.csvwithheadto confirm rows exist.
- Clear actor separation: agents are narrowly scoped (inventory, quoting, ordering) which aids testability and maintainability.
- Used an explicit
OrchestrationAgentto keep the end-to-end flow readable and deterministic. - Database-backed transactions allowed persistent, auditable state changes.
- Discount & fulfillment logic (discount applied only when available stock is sufficient) prevented overpromising.
- Dependency management: the execution environment must have
smolagents,sqlalchemy, and other packages installed; this should be declared in arequirements.txtand verified in CI. - Tool typing: agents assert tools are
BaseToolobjects; ensuring all tool functions are decorated with@toolor wrapped is required (I fixed two functions, but confirm all tool functions are decorated consistently). I added a runtime validator and automatic wrapper for tools in each agent's constructor so the AssertionError ("All elements must be instance of BaseTool") won't occur when plain callables are passed. - Concurrency: the DB operations are naive; if this system were to run concurrently, we'd need transaction handling and locking strategies.
Low-effort (quick wins)
- Add
requirements.txtwith pinned versions: pandas, numpy, python-dotenv, sqlalchemy, smolagents
Medium-effort
- Add logging (structured JSON logs) instead of prints.
Higher-effort
- Add concurrency-safe database access (SQLAlchemy session management) with tests simulating concurrent order placement.
- Add an API layer and a lightweight front-end to simulate customer interactions.
The repository includes a Mermaid flowchart that documents the full data and agent interactions:
- Diagram file:
Mermaid Chart - Create complex, visual diagrams with text.-2026-03-14-180536.mmd
Summary of the flow (mapped directly from the Mermaid diagram):
-
Data & DB initialization
quotes.csv->quotes_df(DataFrame)quote_requests.csv->quote_request_df(DataFrame)paper_supplies(list) ->generate_sample_inventory()->inventory(DataFrame)init_database()composestransactions_schema,quotes_df,quote_request_dfandinventory, and returns an initializedEngine/DB (munder_difflin.db)
-
High-level orchestrator (OrchestrationAgent)
-
The Orchestrator receives a free-text request + date and performs three main steps in sequence:
- Inventory check (InventoryAgent)
- Quote generation (QuotingAgent) using the inventory_check
- Order confirmation (OrderingAgent) using the quote_details
-
It also calls
generate_financial_report()as a helper to fetch company status for reporting.
-
-
InventoryAgent (responsibilities & helpers)
check_inventory(request, as_of_date)— parses free-text requests and returnsinventory_check(Dict of requested item -> available stock)get_all_inventory(as_of_date)— helper that returns a Dict of all available items and stock for a dateget_stock_level(item_name, as_of_date)— helper that returns a DataFrame withcurrent_stockfor the itemget_item_price(item_name)— helper returns unit price frominventory
-
QuotingAgent (responsibilities & helpers)
generate_quote(request, inventory_check)— calculatesquote_details(items, price totals, discounts, notes) and usesget_item_pricesearch_quote_history(search_terms)— helper to retrieve historical quotes matching given terms
-
OrderingAgent (responsibilities & helpers)
place_order(quote_details, request_date)— usescreate_transaction()to recordsalesorstock_orders, checksget_cash_balance()before committing, and returnsorder_confirmationget_supplier_delivery_date(start_date, quantity)— helper to estimate lead times
-
Reporting & Outputs
generate_financial_report(as_of_date)— aggregates cash balance, inventory valuation, and top-selling productsrun_test_scenarios()— drives the evaluation overquote_requests_sample.csv, invoking the orchestration for each request and writingtest_results.csv
Diagram notes (explicit links from Mermaid):
- The DB engine is represented as the central cylinder feeding the Orchestrator.
- InventoryAgent connects to
get_all_inventory,get_stock_levelandget_item_price. - QuotingAgent connects to
generate_quoteandsearch_quote_historyand consumesinventory_check. - OrderingAgent connects to
place_order,create_transaction, andget_cash_balanceand producesorder_confirmation. test_results.csvis the final sink capturing orchestration outputs for each processed request.
I enclose same diagram in PNG and SVG formats.
- Path:
project_starter_Elena.py - Status: updated — key inventory helpers (
get_all_inventory,get_stock_level) are decorated with@tool; duplicate-definition/indent issues were fixed; file compiles.
- Static/syntax check:
python -m py_compile project_starter_Elena.py— PASS.
MIT license